2016-07-19 3 views
0

このクエリ(スカラー関数)を実行すると、結果が得られます。出荷番号が返されます。私は、パラメータ@POG015246をスワップアウトしかしオープンクエリを使用してリンクサーバーに使用されている特定のVARCHAR値のパラメータをスワップする方法

select ShipmentNo from openquery([SERVER_IP], 'SET FMTONLY OFF EXEC GsvStaging.dbo.Paul_GetPoShippingLabels @CartId = NULL, @CpPoNo = ''G015246''') 

、:戻り値は、この変更にはnullになり、いくつかの理由で

select @ShipmentLabels = ShipmentNo from openquery([SERVER_IP], 'SET FMTONLY OFF EXEC GsvStaging.dbo.Paul_GetPoShippingLabels @CartId = NULL, @CpPoNo = ''@PO''') 

。両方のための

マイreturn文は次のとおりです。@ShipmentLabelsが必要な戻り値です

RETURN ISNULL(@ShipmentLabels, @PO) 

。それはnullであるため、代わりに@POを返します。その結果、正しいと思われるG015246になります。

私は@POパラメータをSQL文にどのように追加したのですか?

機能(fnGetTheShippingLabels)呼び出すストアドプロシージャ: 私はこのSPが出発点である記述するための最良の方法を推測します。

ALTER PROCEDURE [dbo].[StartingSP] 
    @JobId INT = 1 

AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @ErrorMsg VARCHAR(256) 


    SELECT OC.PoNo, 
      V.FirstName, 
      V.LastName, 
      dbo.fnGetTradeAppFacilityName(NULL,OC.PoNo) TradeAppFacilityName, 
      OC.ReportFileName, dbo.fnGetTheShippingLabels(NULL,OC.PoNo) ShippingLabels 

    FROM  PoHdr P 
     INNER JOIN OrderConfirmation OC ON 
      OC.PoNo = P.PoNo 
     INNER JOIN CpVendor V ON 
      V.VendNo = P.VendNo 
    WHERE OC.JobId = @JobId 

    SELECT @ErrorMsg ErrorMsg 

END 

上記のように、この関数はSPのSELECT文にあります。

コンプリートスカラー関数:

ALTER FUNCTION [dbo].[fnGetTheShippingLabels] 
(
    @PoHdrRecId INT, 
    @PoNo VARCHAR(20) 
) 
RETURNS VARCHAR(220) 
AS 
BEGIN 
DECLARE @PO VARCHAR(20)= @PoNo 
DECLARE @ShipmentLabels VARCHAR(220) 

    select @ShipmentLabels = ShipmentNo from openquery([SERVER_IP], 'SET FMTONLY OFF EXEC GsvStaging.dbo.Paul_GetPoShippingLabels @CartId = NULL, @CpPoNo = ''G015246''') 
--FROM dbo.PoHdr WHERE PoNo = @PoNo 

    -- Return the result of the functionRETURN ISNULL(@ShipmentLabels, @PO) 

END 

今書き込みクエリの別の方法をしようと、これはFYI動作しません:

Declare @TSQL VarChar(8000) 

    set @TSQL = N'select @ShipmentLabels = ShipmentNo from openquery([SERVER_IP],SET FMTONLY OFF EXEC GsvStaging.dbo.Paul_GetPoShippingLabels @CartId = NULL, @CpPoNo =' + @PO +'' 
    exec sp_executesql @TSQL, N'@ShipmentLabels output', @ShipmentLabels = @ShipmentLabels out 
+0

私はこれを試したことがない - しかし、あなたは、引用符なしでそれを試してみましたか? '@CpPoNo = '@ PO''' SQL Serverはあなたのパラメータを文字列リテラル(VARCHAR)として読み込んでいます。 – scsimon

+0

私はこの権利を行使しないかもしれませんが、 '@CpPoNo = '@ PO'''と' @CpPoNo = @ PO''は実行されません。後者はメッセージにエラーが返されました... "遅延された準備は完了できませんでした。" メッセージ8180、レベル16、状態1、行1 ステートメントを準備できませんでした。 メッセージ137、レベル15、状態2、行1 スカラー変数 "@PO"を宣言する必要があります。 – user1869407

+0

私はあなたのSPにこれが気づいたばかりです。あなたは+でConcatする必要があります。 '@CpPoNo = '+ @ PO' – scsimon

答えて

0

を、私はそれは2つの方法で行うことができることを確認します

オプション1 動的クエリを作成して渡す出力パラメータ

Declare @TSQL VarChar(8000) 
DECLARE @SQ VARCHAR(4) = '''' 
DECLARE @paramDef VARCHAR(100) 

set @TSQL = N'select @ShipmentLabels = ShipmentNo from openquery([SERVER_IP],SET FMTONLY OFF EXEC GsvStaging.dbo.Paul_GetPoShippingLabels @CartId = NULL, @CpPoNo =' + @SQ + @PO + @SQ + ')' 
SET @paramDef = N'@ShipmentLabels VARCHAR(1000) OUTPUT' 
exec sp_executesql @TSQL, @paramDef, @ShipmentLabels = @ShipmentLabels OUTPUT 

オプション2一時テーブルに値を取得し、一時テーブルから値を読んで、動的なクエリを作成します。

Declare @TSQL VarChar(8000) 
DECLARE @SQ VARCHAR(4) = '''' 
DECLARE @ShipmentNo VARCHAR(1000) 
set @TSQL = N'select ShipmentNo from openquery([SERVER_IP],SET FMTONLY OFF EXEC GsvStaging.dbo.Paul_GetPoShippingLabels @CartId = NULL, @CpPoNo =' + @SQ + @PO + @SQ + ')' 

CREATE TABLE #T 
(
    temp VARCHAR(max) 
) 
INSERT INTO #T 
EXEC(@TSQL) 

SELECT @ShipmentNo = temp from #t 
SELECT @ShipmentNo 
drop table #t 

ストアドプロシージャとの完全なソリューションは、私は、カーソルおよびすべてでそれを書かれている、ように見えますが、それはまだパフォーマンスを向上させることができ、私たちはあなたのDBの設計に制限されて、これは私たちができる最善のソリューションですあなたのために提供する。

ALTER PROCEDURE [dbo].[StartingSP] 
    @JobId INT = 1 

AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @ErrorMsg VARCHAR(256) 
    DECLARE @PoNO VARCHAR(1000) 

    Declare @TSQL VarChar(8000) 
    DECLARE @SQ VARCHAR(4) = '''' 
    DECLARE @ShipmentNo VARCHAR(1000) 
    set @TSQL = N'select ShipmentNo,' + @SQ + @PO + @SQ +' as PoNo from openquery([SERVER_IP],SET FMTONLY OFF EXEC GsvStaging.dbo.Paul_GetPoShippingLabels @CartId = NULL, @CpPoNo =' + @SQ + @PO + @SQ + ')' 

    CREATE TABLE #T1 
    (
     temp VARCHAR(max) 
    ) 
    INSERT INTO #T1 
    EXEC(@TSQL) 

    SELECT OC.PoNo, 
      V.FirstName, 
      V.LastName, 
      dbo.fnGetTradeAppFacilityName(NULL,OC.PoNo) TradeAppFacilityName, 
      OC.ReportFileName 
      ,'' as 
      --, dbo.fnGetTheShippingLabels(NULL,OC.PoNo) ShippingLabels 
    INTO #T 
    FROM  PoHdr P 
     INNER JOIN OrderConfirmation OC ON 
      OC.PoNo = P.PoNo 
     INNER JOIN CpVendor V ON 
      V.VendNo = P.VendNo 
    WHERE OC.JobId = @JobId 



    Declare @TSQL VarChar(8000) 
    DECLARE @SQ VARCHAR(4) = '''' 
    DECLARE @ShipmentNo VARCHAR(1000) 
    CREATE TABLE #T1 
    (
     PoNo VARCHAR(1000),ShipmentNo VARCHAR(max) 
    ) 

    DECLARE vend_cursor CURSOR 
     FOR SELECT PoNO FROM #T 
    OPEN vend_cursor 

    FETCH NEXT FROM vendor_cursor 
    INTO @PoNO 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 

     set @TSQL = N'select ShipmentNo,' + @SQ + @PO + @SQ +' as PoNo from openquery([SERVER_IP],SET FMTONLY OFF EXEC GsvStaging.dbo.Paul_GetPoShippingLabels @CartId = NULL, @CpPoNo =' + @SQ + @PO + @SQ + ')' 

     INSERT INTO #T1 
     EXEC(@TSQL)  

     FETCH NEXT FROM vendor_cursor 
     INTO @PoNO 
    END 
    CLOSE vendor_cursor 
    DEALLOCATE vendor_cursor 

    UPDATE T 
    SET T.ShippingLabels = T1.ShipmentNo 
    FROM #T T 
    JOIN #T1 T1 
    ON T.PoNo = T1.PoNo 

    SELECT @ErrorMsg ErrorMsg 

END 
+0

次のエラーが表示されます。関数内でのみ、関数と拡張ストアドプロシージャが実行できます。 System.Data.SqlClient.SqlException(0x80131904):関数内でのみ、関数と一部の拡張ストアドプロシージャを実行できます。動的SQLの使用。 – user1869407

+0

上記の「更新」コードを参照 – user1869407

+0

いずれのオプションも機能していません。オプション2のエラーは、 "関数内で副作用演算子 'SELECT'を無効にすることです。 – user1869407

関連する問題