2017-07-25 20 views
0

SQL Server 2008にあるテーブルがあります。テーブルにはCC_TERMIDという名前のフィールドがあり、数値フィールドです。私は現在のTermIDを検索したいと思っているOracleサーバー上のデータを持っており、これをSQLテーブルに対する変数として使用したいと考えています。私はかなり私のエラーがデータ型の不一致にあると確信していますが、私は変数のデータを格納する方法を見つけることができません。今、私がいることを利用したいカンマを含むSQL Where句の変数を使用

DECLARE @TERMS nvarchar(50) 
    SET @TERMS = (SELECT * FROM OPENQUERY(POWERSCHOOL, 
    ' 
    SELECT TO_NUMBER(LISTAGG(ID, '','') WITHIN GROUP (ORDER BY SCHOOLID)) 
    FROM TERMS 
    WHERE SYSDATE + (SELECT FIRSTDAY - SYSDATE 
        FROM TERMS 
        WHERE ISYEARREC = 1 AND YEARID = (SELECT MAX(SUBSTR(TERMID, 1,2)) 
                 FROM CC) AND SCHOOLID = 51) BETWEEN FIRSTDAY AND LASTDAY AND SCHOOLID = 51 
    ')) 

これは2700,2701,2703,2704

のようなデータを返します。ここでは

は私はオラクルから必要なデータを取得するためにOPENQUERYを使用して作成しています私の変数でありますこのような私のSQLテーブルに対してクエリ内の変数:「数値への変換エラーのデータ型はnvarchar」:もちろん

SELECT TCH_EMAIL_ADDR, TCH_LAST_NAME, TCH_FIRST_NAME, CC_TERMID 
    FROM ZPS_CCRAW 
    WHERE CC_TERMID IN (@TERMS) 

私はエラーを取得します。私はこのようなデータ型はnvarcharに/ CONVERTのCC_TERMIDをキャストしようとしている:

SELECT TCH_EMAIL_ADDR, TCH_LAST_NAME, TCH_FIRST_NAME, CC_TERMID 
    FROM ZPS_CCRAW 
    WHERE CAST(CC_TERMID AS NVARCHAR(50)) IN (@TERMS) 

しかし、私は何も結果が返されません取得します。 @TERMSを削除して2700,2701,2703,2704と入力すると、期待どおりにデータが返されます。

私は文章の作成に関しては専門家の近くにいません。私はこのようなトラブルに私を連れて行くには十分だが、そこから抜け出す方法を知るには十分ではない。誰も私が私が探しているものを達成するのを助けることができますか?

+1

なぜ変数を使用しますか?あなたの質問を 'in'に入れてください。 –

+0

Ilya Bursov - 私の問題は、TermIDが日付によって変わるということです。この場合、第1四半期はtermIDの2700,2701,2703,2706になります。 10月の終わりに向けてクォータ2ヒットが出ると、IDの2700,2701,2703,2707が必要になります。各四半期には異なるIDセットがあります。来年が来ると、今は2800ものすべてに変わります。私はセットを探していて、スクリプトを忘れるので、手動でコードを調整する必要はありません。 – rockman20

+0

あなたのコメントは私の質問にどのように関連していますか? –

答えて

0
あなたは私を許しする必要があります

は、私は、Oracleとの良好ではないよ、それは私があなたのサブクエリへの変更はかなりの仕事をしないことが可能です。しかし基本的には、リストをシリアライズしないでください。それを設定データのままにしておきます。

DECLARE @TERMS table (Id int) 

    insert into @TERMS (Id) 
    SELECT ID FROM OPENQUERY 
    (
     POWERSCHOOL, 
     'SELECT DISTINCT ID 
     FROM TERMS 
     WHERE SYSDATE + (SELECT FIRSTDAY - SYSDATE 
         FROM TERMS 
         WHERE ISYEARREC = 1 AND YEARID = (SELECT MAX(SUBSTR(TERMID, 1,2)) 
                  FROM CC) AND SCHOOLID = 51) BETWEEN FIRSTDAY AND LASTDAY AND SCHOOLID = 51' 
) 

次に、このような何かにあなたのその後のクエリを変更します

SELECT TCH_EMAIL_ADDR, TCH_LAST_NAME, TCH_FIRST_NAME, CC_TERMID 
FROM ZPS_CCRAW 
WHERE CC_TERMID IN (select Id @TERMS) 

または

SELECT TCH_EMAIL_ADDR, TCH_LAST_NAME, TCH_FIRST_NAME, CC_TERMID 
FROM ZPS_CCRAW a 
INNER JOIN @TERMS b 
     on a.CC_TERMID = b.Id 

注意、あなたはOPENQUERYからではなく、テーブル変数でそれらをダンプするよりも、直接同じことを行うことができますもしあなたが好きなら。

何基本的に起こっていることは、あなたが

... CC_TERMID 
... 2700 
... 2701 
... 2703 
... 2704 

...のように見えるのテーブルを持っている...あなたは現在、私のCC_TERMIDは、文字列リテラル"2700,2701,2703,2704"

に等しいすべての行を与える」言っています
+0

私の答えはSQL Serverに関連しています。彼のリモートクエリの内容は、PL/SQL(AKA Oracle)で書かれています。これは彼の記事の2行目と同様です。それは私が構文を知らない部分です。しかし、私はそれをかなり明確にしたと思った。 '@ ... 'のものは変数宣言であり、OPにもそれらがあります。 – Xedni

+1

Xedniありがとう!変数として表を宣言できることはわかりませんでした。私が変更しなければならなかったのは、(select Id @TERMS)から(select from id FROM @TERMS)でした。そうでなければ、これは完璧な答えでした。私は変数としてテーブルを宣言できることを学んだことにも感謝します。 – rockman20

+0

うれしい私は助けることができます。 – Xedni

0

あなたのOracleクエリはうまくいきます。これはSQL Serverがこの文を解釈する方法ですが、SQL Serverを使用してからしばらくしていますが、この方法で変数を使用することはできません。 @termsは文字列ではなく値のリストとして解釈されるように動的クエリを使用します。

+0

DSQLでこれを行う際の主な問題は、それがインジェクションプルーフではないということです。 – Xedni

+0

変数がユーザーインターフェイスフィールドではなくselectステートメントから作成されるため、注入のリスクが最小限に抑えられます。 selectステートメントは、注入が困難な数字のリストを返しています。 – LAS

関連する問題