- PR -

OPENQUERYの文字列

投稿者投稿内容
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-01-28 17:15
こあらさん、ご丁寧な説明ありがとうございます。

あと、前回エラーとなったSQL文ですが、下記のようにすると成功しました。
---------------------------------------------------------------
SET @SQL = 'SELECT *
FROM OPENQUERY(AS400,''SELECT COUNT(*) FROM HDATALIB.HSE030P' + ' WHERE '

SET @PRODUCT = '((SH02 = ' + '''''' + @PR1 + '''''' + ' AND ' + 'SH03 = ' + '''''' + @PR2 + '''''' + ') OR '
+ '(SH02 = ' + '''''' + @PR3 + '''''' + ' AND ' + 'SH03 = ' + '''''' + @PR4 + '''''' + ') OR '
+ '(SH02 = ' + '''''' + @PR5 + '''''' + ' AND ' + 'SH03 = ' + '''''' + @PR6 + '''''' + '))' + ''')'
SET @SQL = @SQL + @PRODUCT
EXECUTE sp_executesql @SQL
---------------------------------------------------------------

こあら
大ベテラン
会議室デビュー日: 2007/06/26
投稿数: 157
投稿日時: 2008-01-30 11:03
今回の件にはあまり関係無いかもしれませんが、
パラメータは、QUOTENAME関数でシングルクォートをエスケープできるようにしておいた方が良いです。

SQLインジェクション対策という程のことでもなく、
例えば、パラメータが入力値の場合、ユーザーがシングルクォートを入力したら
異常終了するストアドでは使い勝手が悪いでしょう。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-01-31 13:26
REPLACE関数はしっていましたが、QUOTENAME関数は初めて知りました。
 http://blogs.sqlpassj.org/yoshihirokawabata/articles/8218.aspx

今回私が作成しているストアドは下記のような方法で使用します。
 @ユーザーPCのVBプログラム
     ↓
 ASQLサーバーのストアド ・・・ ここの部分
     ↓
 BAS/400のデータベース

理想は@のVB上でユーザーからの任意のパラメータを取得して、Aのストアドへパラメータを渡し作成されたSQL文を使用し、Bからデータを取得する事です。
しかし、@で取得したパラメータを変数にセットし、そのまま変数をA上でSQL文受け渡す事が出来ません(拡張ストアドじゃないと無理?)
 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=42624&forum=7
その為、@で取得したパラメータをA上で判断し、予め用意した文字列をいくつか組み合わせてOPENQUERY用のSQL文を作成し、Bへ対して実行しています。
その為、ユーザーから「'」付きパラメータを受け取り以上終了するといった心配は無いかもしれません。

しかし上記の方法だと、予測できる範囲のパラメータしか対応できません。
こあらさんはストアドに渡されたパラメータをそのままOPENQUERYで使用する事はできますでしょうか?これが何らかの方法で実現できれば大きな進歩になるのですが><"
こあら
大ベテラン
会議室デビュー日: 2007/06/26
投稿数: 157
投稿日時: 2008-01-31 13:55
ごめんなさい。何を聞かれているのか良く分かりません。

> ストアドに渡されたパラメータをそのままOPENQUERYで使用する

(1)ユーザーPCのVBプログラムから(2)SQLサーバーのストアドへパラメータを渡す方法?
(2)SQLサーバーのストアドから(3)AS/400のデータベースへパラメータを渡す方法?

文面からは両方出来ているように読み取れたのですが、読み違いでしょうか。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-01-31 18:47
分かりにくくてすみません!

現在は下記ストアドAのようにVBから渡されたパラメータP1の値によってPR1の値をセットします。その後、変数にセットされた文字列を組み合わせSQL文を作成し、OPENQUERYを実行します。
ストアドA--------------------
CREATE PROCEDURE A (
@P1 VARCHAR(10)
)
AS
DECLARE @SQL NVARCHAR(300)
DECLARE @PRODUCT NVARCHAR(300)
DECLARE @PR1 NVARCHAR(10)

IF @P1 = '1' THEN ・・・ ここで@PR1へセットする値を判断している
SET @PR1 = '41'
ELSE IF @P1 = '2' THEN 
SET @PR1 = '42'
END IF

SET @SQL = 'SELECT * FROM OPENQUERY(AS400,''SELECT COUNT(*) FROM FDATALIB.HSE030P'
+ ' WHERE '

SET @PRODUCT = '(SH02 = '
+ @PR1
+ ')'
+ ''')'

SET @SQL = @SQL + @PRODUCT
EXECUTE sp_executesql @SQL
--------------------------------

しかし理想は下記ストアドBで、VBから受け取った値をそのままSQL文として扱いリンク先のAS/400からデータを取得したいのです。しかしOPENQUERYでしていするSELECT文は文字列じゃないといけないようで、P1をうまくAS/400へ受け渡す事ができません。
ストアドB--------------------
CREATE PROCEDURE B (
@P1 VARCHAR(10)
)
AS
DECLARE @SQL NVARCHAR(300)
DECLARE @PRODUCT NVARCHAR(300)

SET @SQL = 'SELECT * FROM OPENQUERY(AS400,''SELECT COUNT(*) FROM FDATALIB.HSE030P'
+ ' WHERE '

SET @PRODUCT = '(SH02 = '
+ @P1 ・・・ ストアドがVBから受け取った値を使用してSQL文を作成する
+ ')'
+ ''')'

SET @SQL = @SQL + @PRODUCT
EXECUTE sp_executesql @SQL
--------------------------------

ストアドAはP1が「1」か「2」といった判断しか出来ず、「3」が来た場合には対応できません。ユーザーから渡されたパラメータで動的にOPENQUERYのSQL文を作成したいと考えています。
こあらさん、内容が伝わりましたでしょうか?
こあら
大ベテラン
会議室デビュー日: 2007/06/26
投稿数: 157
投稿日時: 2008-01-31 22:13
引用:

理想は下記ストアドBで、VBから受け取った値をそのままSQL文として扱いリンク先のAS/400からデータを取得したいのです。しかしOPENQUERYでしていするSELECT文は文字列じゃないといけないようで、P1をうまくAS/400へ受け渡す事ができません



具体的にどんなエラーなんでしょう?



もし「@P1がUNICODE文字列で無いから」だったら、

> @P1 NVARCHAR(10)
ストアドの引数をNVARCHARで定義するとか、

> SELECT @PR1 = CAST(@P1 as NVARCHAR)
NVARCHARに変換してやるとか、試してみてはどうでしょうか。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-02-05 18:05
こあらさん、返答が遅くなりすみませんでした。

私が行ないたい理想のストアドは出来ました!以前はOPENQUERYの文字列内に変数をうまくセットできなかったのが原因で、エラーが表示されていました。それに、「OPENQUERYには変数を渡せない」といった説明がネット上にあった為にうまくいかない事をあきらめていました。
今回こあらさんにOPENQUERYについて教えていただいたおかげで、今後の開発がスムーズに行きそうです。ありがとうございました!
今後ともよろしくお願いします。

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