2016-07-19 3 views
0

이 쿼리를 실행할 때 (필자는 스칼라 함수 임) 원하는 결과를 얻습니다. 배송 번호를 반환합니다. 내가 매개 변수 @POG015246을 교환하지만openquery가있는 연결된 서버에 사용되는 특정 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 인 것으로 끝납니다.

SQL 문에 @PO 매개 변수를 추가 한 방법에 아무런 문제가 없습니까?

기능 (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 

지금 쓰는 쿼리의 다른 방법을 시도,이 참고하시기 바랍니다 작동하지 않습니다

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에 나타났습니다. 당신은 단지 +와 연결될 필요가 있습니다. '@CpPoNo = '+ @ PO' – scsimon

답변

0

을 나는 그것이 두 가지 방법으로 수행 할 수 있습니다 것을 볼

옵션 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