@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

OPENQUERYでのパラメータ指定方法

投稿者投稿内容
のりちゃん
会議室デビュー日: 2007/09/19
投稿数: 15
投稿日時: 2007-12-10 15:49
いつもお世話になっております。
OPENQUERYについて質問があります。
例えば、
CREATE Procedure dbo.AA_S_0001
(
@資産番号開始 varchar(12)
)
As
SELECT *
FROM OPENQUERY(SAPR3P,'SELECT A.ANLN1 FROM SAPR3P.R3P.dbo.ANLA A
WHERE (A.ANLN1 =@資産番号開始)')
というようなストアドプロシージャを作成したいのですが@資産番号開始のパラメータを
使用する時どのようにして記述すればいいのでしょうか?(これではエラーになってしまいます。)
初心者的な質問かもしれませんが、よろしくお願いいたします。
nakaP
大ベテラン
会議室デビュー日: 2005/09/27
投稿数: 138
お住まい・勤務地: 高知
投稿日時: 2007-12-10 16:07
こんにちは。
引用:

SELECT *
FROM OPENQUERY(SAPR3P,'SELECT A.ANLN1 FROM SAPR3P.R3P.dbo.ANLA A
WHERE (A.ANLN1 =@資産番号開始)')



エラーの内容が書かれてませんので憶測ですが。

SELECT *
FROM OPENQUERY(SAPR3P,'SELECT A.ANLN1 FROM SAPR3P.R3P.dbo.ANLA A
WHERE (A.ANLN1 =' + @資産番号開始 + ')')

こうじゃないですかね。元のままだと、@資産番号開始という文字列のままでクエリを実行しています。
DBMSが書かれてないのでわかりませんが、Microsoft SQLServerだとクエリアナライザとかで
書いてみると文字列部分とか色分けしてくれるので問題箇所が見つけやすいですよ。
のりちゃん
会議室デビュー日: 2007/09/19
投稿数: 15
投稿日時: 2007-12-10 16:29
J.J.様ご返信ありがとうございます。
最初の記述方法はあくまでも例で記述しました。構文チェックは通るのですが
おっしゃられるとおり文字列として認識されるので実際の抽出がうまく働きません。

J.J.様がおっしゃられた方法で構文チェックをかけると
---------------------------
Microsoft SQL-DMO (ODBC SQLState: 42000)
---------------------------
エラー 170: 行 ○○: '+' の近くに無効な構文があります。
---------------------------
OK
---------------------------
※○は行数です。
というようなエラーがかえってきてしまいます。
nakaP
大ベテラン
会議室デビュー日: 2005/09/27
投稿数: 138
お住まい・勤務地: 高知
投稿日時: 2007-12-10 16:47
ごめんなさい。OPENQUERYでは変数は指定できないとマニュアルにありましたorz
http://msdn2.microsoft.com/ja-jp/library/ms188427.aspx

OPENQUERYで抽出した表に対してWhere句で条件指定するという方法なら取れるようです。

例:
declare @param int
SELECT *
FROM OPENQUERY(linkserver,'SELECT column1,column2 FROM tableA')
WHERE column = @param
のりちゃん
会議室デビュー日: 2007/09/19
投稿数: 15
投稿日時: 2007-12-20 18:09
J.J.様ご返答ありがとうございました。
OPENQUERY内にWHERE条件を記述できないことは分かりました。
しかし外に書くとなると速度がかなり落ちてしまうと思います。
そこで、例えば、WHERE句を含むSQLを文字列としてある変数に渡し、その変数を
OPENQUERYで読むようなやり方で出来ないでしょうか?
どうしても速度を落としたくないので、
リンクサーバー内でパラメータ指定を行いたいと思っているのですが。

ご存知の方、いらっしゃいましたらご教授下さい。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-03-07 19:36
お世話になります。

SQLサーバー2000(SP4)でストアドプロシージャを開発しています。

以下のように2つのテーブルがあり、
ユーザーが指定したグループ名が
テーブルGのグループ名にあれば子グループ名を抽出し、
テーブルGに値が無い場合にはテーブルMを見に行きメンバー名を抽出する
ようなストアドを考えています。
○具体例
 「商学部」を指定した場合、テーブルGから「商学科」と「商法学科」を取得し、
 「商学科ゼミ1」を指定した場合にはテーブルMから「Bさん」を抽出する。

■テーブルG ・・・ グループの親子関係を管理するテーブル
グループ名 |子グループ名
---------------------------
商学部   |商業科
商学部   |商法学科
商学科   |商学科ゼミ1
商学科   |商学科ゼミ2

■テーブルM ・・・ グループの所属メンバーを管理するテーブル
グループ名 |メンバー名
---------------------------
商法学科  |Aさん
商学科ゼミ1|Bさん
商学科ゼミ2|Cさん

■現在考えたストアド-----------------------------------
@G = '商学科ゼミ1'
@P = SELECT COUNT(*) FROM テーブルG WHERE グループ名 = @G ・・・@
IF @P > 0
BEGIN
SELECT メンバー名 FROM テーブルM WHERE グループ名 = @G ・・・A
END
ELSE
BEGIN
SELECT 子グループ名 FROM テーブルG WHERE グループ名 = @G ・・・B
END
-----------------------------------------------------
しかしこれだと@の時点で一度テーブルをリードし、結果に合わせて再度AかBを行うといった処理の無駄が発生します。上記以外の方法で、処理が簡潔な方法は無いでしょうか?アドバイスをお願いします。
OakBow
ベテラン
会議室デビュー日: 2007/09/15
投稿数: 51
投稿日時: 2008-03-07 22:23
なんで別のスレッドにぶら下がってるんでしょうか。。

コード:
SET @G = '商学科ゼミ1';
IF EXISTS(SELECT * FROM テーブルG WHERE グループ名 = @G)
BEGIN
 SELECT メンバー名 FROM テーブルM WHERE グループ名 = @G;
END
ELSE
BEGIN
 SELECT 子グループ名 FROM テーブルG WHERE グループ名 = @G;
END



普通に書くならこれかな?
単にあるかどうか調べるならEXISTSのほうが数段早いと思います。

あとはこんなの?

コード:
 SET @G = '商学科ゼミ1';
 SELECT メンバー名,dummy AS 子グループ名 FROM テーブルM WHERE グループ名 = @G
 UNION
 SELECT dummy AS メンバー名,子グループ名 FROM テーブルG WHERE グループ名 = @G;



環境ないので検証はしてません。
後ろのほうはかなり思いつき。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-03-08 08:47
すみません、「新規投稿」と「返答」のボタンを間違えてしまい他の方のスレッドに書き込んでしまいました。
のりちゃんさん、ごめんなさい。

OakBowさん、返答ありがとうございます。
「EXISTS」は使えそうですね、試してみます!それに異なるテーブルのカラムを揃える事でUNIONするという手もいいですね。
あとはIFを使うのとUNIONするのとどちらが処理速度が速いか試してみて決めようと思います!分かり易いアドバイスありがとうございました、今後とも宜しくお願いします!

スキルアップ/キャリアアップ(JOB@IT)