マンガでよめる痔のこと・薬のこと

いつもお世話になっております、ありがとうございます。

SQL文を文字型変数に格納し、EXECUTEで発行する方法のことを何とか、といったと思うのですが、ド忘れしてしまいました。

あいまいな記憶では「外部○○」とか、そんな感じだったと思うのですが・・・

よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

動的クエリですか?



  http://msdn2.microsoft.com/ja-jp/library/ms18833 …
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました!
御礼が遅くなり、申し訳ありません。

その通りでした!
ありがとうございました。

お礼日時:2008/03/07 11:04

動的SQLとか動的クエリと言います。



http://www.microfocus.co.jp/manuals/SE40/dbdyna. …

SQL Server 2000ではNVARCHER型の変数に対して有効ですが、
変数を+で連結すれば最大80000byteまでの文字列を動的SQLで発行可能だったと思います。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました!
御礼が遅くなり、申し訳ありません。

その通りでした!
文字数の制限もあるのですね。
じっくり調べていきたいと思います。

ありがとうございました!

お礼日時:2008/03/07 11:06

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qvarchar型の入力できる最大文字数について

varcharでサイズを8000にしたフィールドに1000文字(例えば’aaa・・・「a」を1000文字・・・’)INSERTした後にそのフィールドをSELECTすると256文字しか入っていません。どうしてなんでしょうか?

SELECT、INSERTなどのSQLの実行は”クエリ アナライザ”や”SQL Server Enterprise Manager”で試しました。

SQLServer初心者です。何卒宜しくお願い致します。

Aベストアンサー

使用しているツールの側で、文字列の受け取りバッファの大きさを256文字分しか用意していないのかもしれません。

そのvarcharフィールドに対して

SELECT LEN(そのフィールド) FROM テーブル

を実行すると、そのフィールドの中の文字列の長さが返りますが、それも256でしょうか。

もし上記SELECTの結果が256ではない(もっと大きい)場合は、256文字しか表示されないのはツール側の受け取りバッファが小さいだけで、実際に記録されている文字列はもっと長いということになります。

#SQL Server 6.5までvarcharの長さは255文字までに制限されていましたが、SQL Server 7.0以降ではvarcharの長さは8000文字まで使用できます。

Q【Transact-sql】 where条件、inのパタメータを変数に持たせる方法

inの中の値を変数に持たせ、実行したいのですが方法がわかりません。
以下に、問題となっているsqlを記載しました。
aテーブルのIDはsmallint型で、varchar型等への型変更不可とします。

cast(ID as varchar(100)) in (@ID) 等も試してみたのですが、
'1,2,3'をin内の1データとみなしてしまっているようで、正しい結果を
返してくれませんでした。

declare @ID varchar(100)
set @ID = '1,2,3'
SELECT * FROM a WHEREID in (@ID)

Aベストアンサー

条件式の値部分(「列名=変数」や「列名 between 変数1 and 変数2」でなく、式全体を変えたいようなケース(inでの値の個数変更を含む)では、動的SQLを使う必要があります。
SQL Serverで動的SQLを使い、select文で複数行を得る場合の方法についてはあまり詳しくないので、ヒントという形でアドバイスします。

こんな感じで、文字列でカーソル定義(この時、SELECT文の条件式を変える)し、カーソルで操作する形になると思います。

execute('DECLARE tb CURSOR FOR SELECT * FROM tablename' + @yymm)

Qクロス集計で、列を動的に

SQLserverでのクロス集計についてご質問ですが、
クロス集計後の結果、列を動的に変更させる必要がある場合、ストアドプロシージャで処理しなければならないかとは思うのですが、
例えば
T_売上
番号,日付,数
1,2004/09/10,10
1,2004/09/14,20
1,2004/09/18,10
2,2004/09/10,20
2,2004/09/14,20
3,2004/09/18,10

番号,2004/09/10,2004/09/14,2004/09/18
1,10,20,10
2,20,20,0
3,0,0,10
という形に出力したいときは、具体的にどういう手順でSSQLを作成していけばよろしいでしょうか。
(日付部分が動的に増えたり減ったりします)

Aベストアンサー

declare @sql1 varchar(8000)
declare @sql2 varchar(8000)
declare @i int
declare @fld1 varchar(20)
declare @fld2 varchar(20)
declare @fldx varchar(20)
select @sql1='select T売上.番号'
select @sql2=''
select @fld1='日付'
select @fld2='数'
select @i=0

declare fld_lst cursor for
select distinct convert(varchar,日付,111) as 日付 from T売上 order by 日付

open fld_lst

while @i<100
begin
fetch next from fld_lst into @fldx
if @@fetch_status<>0 break

set @sql1=@sql1+',sum(case when '+convert(varchar,@fld1,111)+'='''+@fldx
+''' then '+@fld2+' else 0 end) as ['+@fldx+']'

set @i=@i+1
end

if @@fetch_status=0
while 1=1
begin
fetch next from fld_lst into @fldx
if @@fetch_status<>0 break
set @sql2=@sql2+',sum(case when '+convert(varchar,@fld1,111)+'='''+@fldx
+''' then '+@fld2+' else 0 end) as ['+@fldx+']'
end

close fld_lst
deallocate fld_lst

exec(@sql1+@sql2+' from T売上'
+' group by T売上.番号 order by T売上.番号')
return

以上でできるはずでは。

declare @sql1 varchar(8000)
declare @sql2 varchar(8000)
declare @i int
declare @fld1 varchar(20)
declare @fld2 varchar(20)
declare @fldx varchar(20)
select @sql1='select T売上.番号'
select @sql2=''
select @fld1='日付'
select @fld2='数'
select @i=0

declare fld_lst cursor for
select distinct convert(varchar,日付,111) as 日付 from T売上 order by 日付

open fld_lst

while @i<100
begin
fetch next from fld_lst into @fldx
if @@fetch_status<>0 bre...続きを読む

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

QVBでストアドの戻りパラメータを受け取る方法

VB6.0からADOを利用してSQLServerのストアドプロシージャを呼出し、戻りパラメータを受け取る方法がありましたら教えてください。よろしくお願いします!

CREATE PROC TEST
(
I_VAL AS INT,
O_VAL AS INT OUTPUT
)

~省略~

Aベストアンサー

#2のxcrOSgS2wYさんが飛ばしているリンク先の、.NETサンプルを書いた者です。

.NETからVB6へのコンバートをやってみました。
(いつもと逆方向への変換なので、違和感がありました^^;;;)

ストアドは、参考URLのまま利用しています。


Option Explicit

Sub Main()
  Const DEF_ストアド名 As String = "ストアド"
  
  Dim l_adoCnn  As ADODB.Connection
  Dim l_adoCmd  As ADODB.Command
  Dim l_adoRec  As ADODB.Recordset
  
  Set l_adoCnn = New ADODB.Connection
  Set l_adoCmd = New ADODB.Command
  
  'コネクション設定
  l_adoCnn.CursorLocation = adUseClient  '← これ重要、結構忘れられる。
  l_adoCnn.Open "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=master;uid=sa;pwd=sa"
  
  With l_adoCmd
    'コネクションをコマンドに設定
    Set .ActiveConnection = l_adoCnn

    'コマンド種別 = ストアド
    .CommandType = adCmdStoredProc
    'ストアド名を指定
    .CommandText = DEF_ストアド名

    'パラメータ追加:戻り値
    .Parameters.Append パラメータ作成(l_adoCmd, "@戻り値", adInteger, 4, adParamReturnValue)

    'パラメータ追加:引数(I/I/O/IO)
    .Parameters.Append パラメータ作成(l_adoCmd, "@パラム1_VAR_I", adVarChar, 12, adParamInput, "abcde")
    .Parameters.Append パラメータ作成(l_adoCmd, "@パラム2_INT_I", adInteger, 4, adParamInput, 2)
    .Parameters.Append パラメータ作成(l_adoCmd, "@パラム3_VAR_O", adVarChar, 26, adParamOutput)
    .Parameters.Append パラメータ作成(l_adoCmd, "@パラム4_INT_IO", adInteger, 4, adParamInputOutput, 3)
  End With

  'ストアド実行
  Set l_adoRec = l_adoCmd.Execute
  

  '実行結果を出力
  Dim i As Integer
  Dim l_str結果 As String
  
  With l_adoCmd
    For i = 0 To .Parameters.Count - 1
      l_str結果 = l_str結果 & i & vbTab & .Parameters(i).Name & vbTab & .Parameters(i).Value & vbCrLf
    Next
  End With
  Call MsgBox(l_str結果, vbInformation, "結果出力")

End Sub

'パラメータ作成関数
Private Function パラメータ作成( _
         ByRef p_adoコマンド As ADODB.Command _
        , ByVal p_strパラメータ名 As String _
        , ByVal p_dtpDBタイプ As ADODB.DataTypeEnum _
        , ByVal p_intサイズ As Integer _
        , ByVal p_pdrパラメータ種別 As ADODB.ParameterDirectionEnum _
        , Optional ByVal p_obj初期値 _
    ) As ADODB.Parameter
    
  Dim l_adoPrm  As ADODB.Parameter

  Set l_adoPrm = p_adoコマンド.CreateParameter(p_strパラメータ名, p_dtpDBタイプ, p_pdrパラメータ種別, p_intサイズ)
  l_adoPrm.Value = IIf(IsMissing(p_obj初期値), vbNull, p_obj初期値)
  
  Set パラメータ作成 = l_adoPrm
End Function

#2のxcrOSgS2wYさんが飛ばしているリンク先の、.NETサンプルを書いた者です。

.NETからVB6へのコンバートをやってみました。
(いつもと逆方向への変換なので、違和感がありました^^;;;)

ストアドは、参考URLのまま利用しています。


Option Explicit

Sub Main()
  Const DEF_ストアド名 As String = "ストアド"
  
  Dim l_adoCnn  As ADODB.Connection
  Dim l_adoCmd  As ADODB.Command
  Dim l_adoRec  As ADODB.Recordset
  
  Set l_adoCnn = New ADODB.Connection...続きを読む

QSQLServerのストアドで戻り値取得したい。

こんにちわ。
いまSQLServer2005でストアドを作成しています。
あるテーブルをSELECTして,あるカラムと件数の両方を出力パラメータに取得したいのですが,
件数は取得できるのですが,カラムが取得できません。
ちなみに下記のようなコードになります。
create procedure funLoginCheck (@UserID char(5), @PassWord varchar(10), @RowCount int output, @DeptID char(2) output)
as select * from MST_Employee
where EmployeeID = @UserID And PassWord = @PassWord; set @deptid = deptid」
deptidを出力パラメータに渡す方法がわかりません。
初歩的なことかもしれませんが,
教えてください。よろしくお願いします。

Aベストアンサー

>deptidを出力パラメータに渡す方法

select @deptid=deptid from MST_Employee
where EmployeeID = @UserID And PassWord = @PassWord

という方法で渡せます。
ところで、この条件でヒットするのは1行だけなのでは?
パラメタ=@RowCountの目的が、よく分かりませんが?
それに今の記述では、@RowCountには何も設定されていません。システムから返される@@ROWCOUNTの内容を、設定したいのでしょうか?

プロシジャとファンクションの定義と実行例を、参考までに示します。

1.プロシジャ
(1)定義
create procedure dbo.funLoginCheck
(@UserID char(5),
@PassWord varchar(10),
@RowCount int output,
@DeptID char(2) output)
as
select @DeptID=deptid
from MST_Employee
where EmployeeID=@UserID
And PassWord=@PassWord
set @RowCount=@@ROWCOUNT

(2)実行
declare @dept char(2)
declare @rowcnt int
exec dbo.funLoginCheck @UserID='U1',@PassWord='P1',
@RowCount=@rowcnt output,@DeptID=@dept output
select @rowcnt,@dept

2.ファンクション
(1)定義
create function dbo.funLoginCheck
(@UserID char(5),
@PassWord varchar(10))
returns char(2)
begin
declare @DeptID char(2)
select @DeptID=deptid
from MST_Employee
where EmployeeID=@UserID
And PassWord=@PassWord
return @DeptID
end

(2)実行
select dbo.funLoginCheck('U2','P2')

>deptidを出力パラメータに渡す方法

select @deptid=deptid from MST_Employee
where EmployeeID = @UserID And PassWord = @PassWord

という方法で渡せます。
ところで、この条件でヒットするのは1行だけなのでは?
パラメタ=@RowCountの目的が、よく分かりませんが?
それに今の記述では、@RowCountには何も設定されていません。システムから返される@@ROWCOUNTの内容を、設定したいのでしょうか?

プロシジャとファンクションの定義と実行例を、参考までに示します。

1.プロシジャ
(1)定義
...続きを読む

QSQLserverのIF文について

どうしてもIF文がうまくいきません
IF文の中にIFを入れ子していますそのIFが複数の条件があります
今までACCESSではELSEIFで条件をいくらでも指定できたのですがSQLの場合はエラーになってしまいます
ご教授おねがいします
------------------------------
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER FUNCTION [dbo].[scfc_part端数処理]
( @PTHASU nvarchar(10), @haken nvarchar(10) )
RETURNS
real
AS
BEGIN
DECLARE @PARTT real
DECLARE @PARTT_H real

if (not(@PTHASU is null))
if @haken='派遣' or @haken='臨時'
if substring(@PTHASU,4,2)>= 50
SET @PARTT = convert(int,LEFT(@PTHASU,2)+1)*60
--ここをいれるとエラー IF substring(@PTHASU,4,2)< 50 and substring(@PTHASU,4,2)>= 20
--ここをいれるとエラー SET @PARTT = convert(int,LEFT(@PTHASU,2)*60 +30
--ここをいれるとエラー if substring(@PTHASU,4,2)< 20
--ここをいれるとエラー SET @PARTT = convert(int,LEFT(@PTHASU,2)*60
ELSE
SET @PARTT = convert(real,LEFT(@PTHASU,2))*60 + convert(real,substring(@PTHASU,4,2))*1

ELSE
SET @PARTT= 0

SET @PARTT_H = convert(real,(floor(@PARTT/60*10000)/10000))

RETURN @PARTT_H

END

どうしてもIF文がうまくいきません
IF文の中にIFを入れ子していますそのIFが複数の条件があります
今までACCESSではELSEIFで条件をいくらでも指定できたのですがSQLの場合はエラーになってしまいます
ご教授おねがいします
------------------------------
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER FUNCTION [dbo].[scfc_part端数処理]
( @PTHASU nvarchar(10), @haken nvarchar(10) )
RETURNS
real
AS
BEGIN
DECLARE @PARTT real
DECLARE @PARTT_H real

if (not(@PTHASU is...続きを読む

Aベストアンサー

マニュアルを読みましょう。

if 条件
真の時の命令文
else
偽の時の命令文

で、真または偽で命令文を2個以上書く場合は、begin~endでブロックを構成する必要があります。

参考URL:http://msdn2.microsoft.com/ja-jp/library/ms182717.aspx

Q【Transact-sql】 execの結果をoutputパラメータに持たせたい

タイトルの通り、execの結果をoutputパラメータに持たせたいのですが、
どうすればご存知の方、ご教授お願いします。以下のように、count(*)の結果を持たせたいです。以下にサンプルコードを記載しました。

---ストアドabc---
( @aWork int output,
@bWork int output,
@cWork int output,
@IDs varchar )

declare @Sql1 varchar(500)
declare @Sql2 varchar(500)
declare @Sql3 varchar(500)
declare @IDs varchar(500)
set = '1,2,3'



set @Sql1 = 'select count(*) from a where id = ' + IDs

-- @aWork = exec(@Sql1)としたい
exec(@Sql1)

set @Sql2 = 'select count(*) from b where id = ' + IDs

-- @bWork = exec(@Sql2)としたい
exec(@Sql2)

set @Sql3 = 'select count(*) from c where id = ' + IDs

-- @cWork = exec(@Sql3)としたい
exec(@Sql3)

タイトルの通り、execの結果をoutputパラメータに持たせたいのですが、
どうすればご存知の方、ご教授お願いします。以下のように、count(*)の結果を持たせたいです。以下にサンプルコードを記載しました。

---ストアドabc---
( @aWork int output,
@bWork int output,
@cWork int output,
@IDs varchar )

declare @Sql1 varchar(500)
declare @Sql2 varchar(500)
declare @Sql3 varchar(500)
declare @IDs varchar(500)
set = '1,2,3'



set @Sql1 = 'select count(*) from...続きを読む

Aベストアンサー

EXECでSQLを動かした場合は、COUNTの結果は取れないですね。

select @aWork = count(*) from a where id = @IDs

でやれば、OUTPUTで結果を返すんですが、どうしてもEXECじゃ
なきゃダメであれば、EXECじゃなく、sp_executesqlを使って、
下記のようにしてみたらどうでしょう?


-- 実行
EXEC sp_executesql
N'select @aWork = count(*) from a where id = @IDs',
N'@aWork int OUTPUT, @IDs varchar(max)',
@aWork output, @IDs

ご参考までに、どうぞ。

参考URL:http://blogs.sqlpassj.org/yoshihirokawabata/archive/2004/11/15/5891.aspx

QSQLServer2005のストアドプロシージャで変数を配列で使用する方法をご教示ください

タイトルの件。調査したのですが、変数を配列でとる方法(宣言の仕方や使用方法)が見つけられませんでした。
ご存知の方、ご教示いただけませんでしょうか?
できれば使用方法が書かれた本やサイトをご紹介いただけると助かります。
それともSQLServer2005のストアドプロシージャでは変数を配列で使用することはできないのでしょうか?
(そんなことはないと思うのですが、探しても出てこないのが不思議です。私の検索方法が悪いからだと思いますが)

以上です。よろしくお願いします。

Aベストアンサー

SQL Serverのストアドプロシージャでは
昔からの仕様で変数には配列が存在しません。

しかしながら、SQL Server 2005はXMLを使用して
配列的に引数を渡すことができます。

http://blogs.sqlpassj.org/yoneda/archive/2005/05/14/9008.aspx

また、内部変数を配列的に使用したければ代わりに、
Table型変数やCursorまたはCursor型変数の使用ができるので、
こちらで配列的な処理が可能でしょう。
(ただし膨大なデータ量だとパフォーマンス劣化の恐れがあります)

Qストアドをまたがるローカル一時テーブル

SQL Server 2005 でストアドプロシージャ(以降SPと省略)
を作成しています。

複数の SP から、構造が同じローカル一時テーブル
(テーブル名が # から始まるテーブル)
を使用したい為、
CREATE するだけのローカル一時テーブル作成SP、
DROP するだけのローカル一時テーブル削除SPを、
それぞれ作成しました。

次に、ローカル一時テーブルを使用したい SP 内で、
ローカル一時テーブル作成SP を EXECUTE 後、
ローカル一時テーブルに対し、INSERT をしたところで
以下のようなエラーとなります。
※INSERT の変わりに、SELECT にしてみても同様でした。

メッセージ 208、レベル 16、状態 0、プロシージャ TEST_SP、行 155
オブジェクト名 '#LocalWorkTable' が無効です。

※TEST_SP とは、ローカル一時テーブルを使用したい SP の名前
 #LocalWorkTable とは、ローカル一時テーブルの名前

グローバル一時テーブル
(テーブル名が ## から始まるテーブル)
に変更すると、正常に動作しましたが、
セッションをまたがって使用させたくないのです。

あと、
ローカル一時テーブル作成SPを使用せずに、
ローカル一時テーブルを使用したい SP 内で、直接 CREATE すれば
正常に動作しましたが、
上記にも書いたように、複数の SP で構造が同じローカル一時テーブル
を使用したいので、できれば、別 SP にしたいと考えております。

ストアドをまたがって、ローカル一時テーブルを使用する事は
できないのでしょうか?

SQL Server 2005 でストアドプロシージャ(以降SPと省略)
を作成しています。

複数の SP から、構造が同じローカル一時テーブル
(テーブル名が # から始まるテーブル)
を使用したい為、
CREATE するだけのローカル一時テーブル作成SP、
DROP するだけのローカル一時テーブル削除SPを、
それぞれ作成しました。

次に、ローカル一時テーブルを使用したい SP 内で、
ローカル一時テーブル作成SP を EXECUTE 後、
ローカル一時テーブルに対し、INSERT をしたところで
以下のようなエラーとなります...続きを読む

Aベストアンサー

#1です。もう一つ代案を書いておきます。
質問者さんは、「テーブル作成SPを作って共用する」ということを考えておられるので、ストアドを1つ作る代わりにテンプレート用の実テーブルを1つ作るのも手かと思います。
・一時テーブルのレイアウトのテーブル(TEMPLATETBL)を準備
・一時テーブルを使うストアドでは、作成用のストアドを呼ぶ代わりに以下を実行する
SELECT TOP 0 * INTO #TEMPTBL FROM TEMPLATETBL

効果はたぶん同じです。
(DROPはDROP TABLE #TEMPTBLですが、先に書いた通り無理に実行しなくても基本的に自動でDROPされます)


人気Q&Aランキング