none
SQLCMDの-QオプションのGO ターミネータについて RRS feed

  • 質問

  • SQLCMDの-Qオプションで、「クエリでは GO ターミネータを使用しないでください。」とあるのですが、これはなぜでしょうか?

    試したところ特に問題なく利用できたのですが。。

    http://msdn.microsoft.com/ja-jp/library/ms162773.aspx

    なお、SQL Server 2012を使用しており、powershellで動的に文字列を生成し、sqlcmdの-Qオプションで渡す使い方をしています。


    2014年6月8日 6:33

回答

  • 私が見る限り、確認手法に問題は無いと思います。
    これは GO が機能していると思われますので、興味深いというか、ぶっちゃけ、謎ですね。

    ちなみに少し脱線すると、2000 時代からあるコマンドである osql でも -q と GO の併用は避けるようにと書かれていました。
    http://msdn.microsoft.com/ja-jp/library/ms162806.aspx

    となると、あとは特定の状況でのみ問題が起きるような仕様上の問題があるからとか、そういった線が疑われますが、そうなってくると闇雲に探してもたどり着くのは無理でしょうね・・・。
    そうなると、有償サポートに問い合わせる、ぐらいしか思いつきません。

    「特定の状況」という線でひとつ気になったのは、sqlcmd も osql も、GO 相当のバッチターミネーターを -c で変更できるんですよね。
    GO 決め打ちだと何か問題があるのかも知れませんね・・・。


    MCITP(Database Developer/Database Administrator)

    • 回答としてマーク threecourse 2014年6月21日 4:07
    2014年6月16日 14:25

すべての返信

  • 動的にどのようなクエリを作成されているのでしょうか? GOは単独行でしか使用できないので、1行の中にクエリと共にGOを指定することはできないと思うのですが・・・? もし、GOの前に改行があるのであれば、そこで一旦クエリが実行されてしまい、GOは実行されずに残るはずです。つまり、終了しないSQLCMDのプロンプトに、
    1> GO
    として残ってしまいます。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2014年6月9日 1:24
  • ご返信どうもありがとうございます。

    以下のようなPowershellスクリプトになります。

    問題なく、33と表示されます。

    $SQL = 
    
    @"
    IF OBJECT_ID ('dbo.func1') IS NOT NULL
        DROP FUNCTION dbo.func1;
    GO
    
    create function dbo.func1(@val int)
    returns int
    as
    begin
     return @val * 11
    end;
    GO
    
    print dbo.func1(3)
    
    "@
    
    & sqlcmd -S "MyServer" -d "MyDatabase" -Q $SQL 

    2014年6月9日 15:02
  • 調べてみましたが、なかなか情報がないですね。PowerShellのスクリプトですが、私の方でも問題なく動作することを確認いたしました。
    ダブルクオートで囲まれたシングルラインのクエリで動作することを前提とした注意なのかなぁ?ぐらいしか思い付きません。
    もう少し調べてみたいところですが、情報が無さすぎですね・・・
    う~ん、申し訳ないです。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2014年6月10日 13:15
  • こんな情報がありました。
    http://www.sqlserverspecialists.com/2012/10/sqlcmd-command-line-option.html
    GO は本来はそこまでの SQL をサーバーに送信する、という動きをしますが、Q オプションでは GO を無視して全体を一度にサーバーに送信する、という動きをする、ということのようです。
    確か SET ~ といった命令などは GO の後で有効になったかと思いますが、そのあたりに動作の差異が出るかも知れません。

    (完全に出遅れ。。。


    MCITP(Database Developer/Database Administrator)

    2014年6月10日 13:33
  • trapemiyaさん、naginoさん、どうもありがとうございます。

    naginoさんに教えていただいたサイトには、以下のようにあるのですが、

    ---------------------------------------------

    Tips and Tricks
    Keep in mind that you cannot submit multiple batches as part of one command. SQLCMD does not recognize batch separators when processing commands for immediate execution.

    ---------------------------------------------

    もしバッチを認識していないとなると、create functionやそれを使った計算がそもそもできない気がします。。

    先ほどのPowershellスクリプトのように書けると柔軟にSQL文を構成できるので、はっきりすると嬉しいのですが、なかなか情報がなさそうですね。。

    2014年6月11日 14:53
  • バッチはコンパイルの単位なので、プランキャッシュを見てコンパイルとキャッシュの単位がどうなっているか、GO でわかれずにひとまとめとなっているのではないか、といったところを確認するのがよさそうなんですが、諸事情で手元に環境が無いので、こちらでは確認できず・・・。


    MCITP(Database Developer/Database Administrator)


    2014年6月11日 15:53
  • 以下を参考にプランキャッシュをみてみました。
    http://stackoverflow.com/questions/7359702/how-do-i-obtain-a-query-execution-plan
    詳しくないため、実験の方法や理解が間違っているかもしれません。

    powershellは以下の通りです。

    $SQL1 = "DBCC FREEPROCCACHE WITH NO_INFOMSGS;"
    
    $SQL2 = 
    @"
    IF OBJECT_ID ('dbo.func1') IS NOT NULL DROP FUNCTION dbo.func1;
    GO
    create function dbo.func1(@val int) returns int as begin return @val * 11 end;
    GO
    IF OBJECT_ID ('dbo.func2') IS NOT NULL DROP FUNCTION dbo.func2;
    GO
    create function dbo.func2(@val int) returns int as begin return @val * 1100 end;
    GO
    print dbo.func1(3)
    print dbo.func2(3)
    GO
    "@
    
    $SQL3 = 
    @"
    SELECT UseCounts, Cacheobjtype, Objtype, TEXT FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text(plan_handle) CROSS APPLY sys.dm_exec_query_plan(plan_handle)
    "@
    
    
    & sqlcmd -S "MyServer" -Q $SQL1 
    & sqlcmd -S "MyServer" -d "MyDatabase" -Q $SQL2 
    & sqlcmd -S "MyServer" -Q $SQL3 -o "CompiledPlan.txt" -s `"`t`"
     

    結果は以下の通りで、GOで分かれてコンパイルされているように思います。

    UseCounts  	Cacheobjtype                                      	Objtype             	TEXT                                                                                                                                                                                                                                                            
    -----------	--------------------------------------------------	--------------------	----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
              1	Compiled Plan                                     	Proc                	create function dbo.func2(@val int) returns int as begin return @val * 1100 end;
                                                                                                                                                                                  
              1	Compiled Plan                                     	Proc                	create function dbo.func1(@val int) returns int as begin return @val * 11 end;
                                                                                                                                                                                    
              1	Compiled Plan                                     	Adhoc               	SELECT UseCounts, Cacheobjtype, Objtype, TEXT FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text(plan_handle) CROSS APPLY sys.dm_exec_query_plan(plan_handle)                                                                                       
              1	Compiled Plan                                     	Adhoc               	SET TEXTSIZE 4096                                                                                                                                                                                                                                               
              1	Compiled Plan                                     	Adhoc               	SET TEXTSIZE 4096                                                                                                                                                                                                                                               




    2014年6月15日 14:44
  • 私が見る限り、確認手法に問題は無いと思います。
    これは GO が機能していると思われますので、興味深いというか、ぶっちゃけ、謎ですね。

    ちなみに少し脱線すると、2000 時代からあるコマンドである osql でも -q と GO の併用は避けるようにと書かれていました。
    http://msdn.microsoft.com/ja-jp/library/ms162806.aspx

    となると、あとは特定の状況でのみ問題が起きるような仕様上の問題があるからとか、そういった線が疑われますが、そうなってくると闇雲に探してもたどり着くのは無理でしょうね・・・。
    そうなると、有償サポートに問い合わせる、ぐらいしか思いつきません。

    「特定の状況」という線でひとつ気になったのは、sqlcmd も osql も、GO 相当のバッチターミネーターを -c で変更できるんですよね。
    GO 決め打ちだと何か問題があるのかも知れませんね・・・。


    MCITP(Database Developer/Database Administrator)

    • 回答としてマーク threecourse 2014年6月21日 4:07
    2014年6月16日 14:25
  • どうもありがとうございます。

    GOが機能しているようで良かったです。

    やはりわからないですよね、ご回答いただきどうもありがとうございました。

    2014年6月21日 4:07