복붙노트

[SQL] OPENQUERY에서 매개 변수를 포함

SQL

OPENQUERY에서 매개 변수를 포함

어떻게 같은 SQL OPENQUERY, 내부 매개 변수를 사용할 수 있습니다 :

SELECT * FROM OPENQUERY([NameOfLinkedSERVER], 'SELECT * FROM TABLENAME
where field1=@someParameter') T1 INNER JOIN MYSQLSERVER.DATABASE.DBO.TABLENAME
T2 ON T1.PK = T2.PK

해결법

  1. ==============================

    1.OPENQUERY 문서에서 그 상태 :

    OPENQUERY 문서에서 그 상태 :

    해결 방법은이 문서를 참조하십시오.

    최신 정보:

    제안, 나는 아래 문서에서 권장 사항을 포함입니다.

    패스 기본 값

    기본 Transact-SQL 문을 알 수 있지만 다음 샘플과 유사 하나 이상의 특정 값을 사용하는 코드에 전달해야하는 경우 :

    DECLARE @TSQL varchar(8000), @VAR char(2)
    SELECT  @VAR = 'CA'
    SELECT  @TSQL = 'SELECT * FROM OPENQUERY(MyLinkedServer,''SELECT * FROM pubs.dbo.authors WHERE state = ''''' + @VAR + ''''''')'
    EXEC (@TSQL)
    

    쿼리 전체 전달

    당신은 전체 거래-SQL 쿼리 또는 다음 예제와 유사하다 연결된 서버의 이름 (또는 둘 다), 사용 코드에 전달해야하는 경우 :

    DECLARE @OPENQUERY nvarchar(4000), @TSQL nvarchar(4000), @LinkedServer nvarchar(4000)
    SET @LinkedServer = 'MyLinkedServer'
    SET @OPENQUERY = 'SELECT * FROM OPENQUERY('+ @LinkedServer + ','''
    SET @TSQL = 'SELECT au_lname, au_id FROM pubs..authors'')' 
    EXEC (@OPENQUERY+@TSQL) 
    

    을 sp_executesql 저장 프로 시저를 사용하여

    다음 샘플과 유사 다층 따옴표 코드를 사용을 방지하려면 :

    DECLARE @VAR char(2)
    SELECT  @VAR = 'CA'
    EXEC MyLinkedServer.master.dbo.sp_executesql
    N'SELECT * FROM pubs.dbo.authors WHERE state = @state',
    N'@state char(2)',
    @VAR
    
  2. ==============================

    2.당신이 그것을 구축 후에는 OPENQUERY 문자열을 실행할 수 있습니다. 이 경로는 사용자의 SQL로하지 CONCATENATE 사용자가 입력 한 텍스트 보안 및 돌봐 생각 가면!

    당신이 그것을 구축 후에는 OPENQUERY 문자열을 실행할 수 있습니다. 이 경로는 사용자의 SQL로하지 CONCATENATE 사용자가 입력 한 텍스트 보안 및 돌봐 생각 가면!

    DECLARE @Sql VARCHAR(8000)
    SET @Sql = 'SELECT * FROM Tbl WHERE Field1 < ''someVal'' AND Field2 IN '+ @valueList 
    SET @Sql = 'SELECT * FROM OPENQUERY(SVRNAME, ''' + REPLACE(@Sql, '''', '''''') + ''')'
    EXEC(@Sql)
    
  3. ==============================

    3.은 MSDN 페이지에서 :

    은 MSDN 페이지에서 :

    기본적으로,이 방법 당신은 동적 쿼리를 발행 할 수 없습니다. 샘플을 시도하고 무엇을 달성하기 위해,이 시도 :

    SELECT * FROM 
       OPENQUERY([NameOfLinkedSERVER], 'SELECT * FROM TABLENAME') T1 
       INNER JOIN 
       MYSQLSERVER.DATABASE.DBO.TABLENAME T2 ON T1.PK = T2.PK 
    where
       T1.field1 = @someParameter
    

    당신의 TABLENAME 테이블 많은 양의 데이터가 포함 분명히 경우,이 역시 네트워크를 통해 이동하고 성능이 저하 될 수 있습니다. 반면에 (따옴표를 이스케이프, SQL 주입)는 간부 접근 방식이 필요로하는 것을, 소량의 데이터를 들면,이 잘 작동하고 동적 SQL 건설 오버 헤드를 피할 수 있습니다.

  4. ==============================

    4.사실, 우리는이 작업을 수행하는 방법을 발견 :

    사실, 우리는이 작업을 수행하는 방법을 발견 :

    DECLARE @username varchar(50)
    SET @username = 'username'
    DECLARE @Output as numeric(18,4)
    DECLARE @OpenSelect As nvarchar(500)
    SET @OpenSelect = '(SELECT @Output = CAST((CAST(pwdLastSet As bigint) / 864000000000) As numeric(18,4)) FROM OpenQuery (ADSI,''SELECT pwdLastSet
                                    FROM  ''''LDAP://domain.net.intra/DC=domain,DC=net,DC=intra''''
                                    WHERE objectClass =  ''''User'''' AND sAMAccountName = ''''' + @username + '''''
                              '') AS tblADSI)'
    EXEC sp_executesql @OpenSelect, N'@Output numeric(18,4) out', @Output out
    SELECT @Output As Outputs
    

    이 변수 @Output에서 OpenQuery를 실행의 결과를 할당합니다.

    우리는 MSSQL 2012 년 저장 프로 시저에 대한 테스트 만, MSSQL 2008+와 함께 작동합니다.

    SQL 서버 (현재 버전을 통해 SQL 서버 2008), 윈도우 Azure SQL 데이터베이스 (현재 릴리스를 통해 초기 등록) : 적용 대상 : Microsoft는 sp_executesql을 (거래-SQL)를 말한다. (http://msdn.microsoft.com/en-us/library/ms188001.aspx)

  5. ==============================

    5.

    DECLARE @guid varchar(36);  select @guid= convert(varchar(36), NEWID() );
    /*
        The one caveat to this technique is that ##ContextSpecificGlobal__Temp should ALWAYS have the exact same columns.  
        So make up your global temp table name in the sproc you're using it in and only there!
        In this example I wanted to pass in the name of a global temporary table dynamically.  I have 1 procedure dropping 
        off temporary data in whatever @TableSrc is and another procedure picking it up but we are dynamically passing 
        in the name of our pickup table as a parameter for OPENQUERY.
    */
    IF ( OBJECT_ID('tempdb..##ContextSpecificGlobal__Temp' , 'U') IS NULL )
        EXEC ('SELECT * INTO ##ContextSpecificGlobal__Temp FROM OPENQUERY(loopback, ''Select *,''''' +  @guid +''''' as tempid FROM ' + @TableSrc + ''')')
    ELSE 
        EXEC ('INSERT ##ContextSpecificGlobal__Temp SELECT * FROM OPENQUERY(loopback, ''Select *,''''' +  @guid +''''' as tempid FROM ' + @TableSrc + ''')')
    
    --If this proc is run frequently we could run into race conditions, that's why we are adding a guid and only deleting
    --the data we added to ##ContextSpecificGlobal__Temp
    SELECT * INTO #TableSrc FROM ##ContextSpecificGlobal__Temp WHERE tempid = @guid
    
    BEGIN TRAN t1
        IF ( OBJECT_ID('tempdb..##ContextSpecificGlobal__Temp' , 'U') IS NOT NULL ) 
        BEGIN
            -- Here we wipe out our left overs if there if everyones done eating the data
            IF (SELECT COUNT(*) FROM ##ContextSpecificGlobal__Temp) = 0
                DROP TABLE ##ContextSpecificGlobal__Temp
        END
    COMMIT TRAN t1
    
    -- YEAH! Now I can use the data from my openquery without wrapping the whole !$#@$@ thing in a string.
    
  6. ==============================

    6.

    SELECT field1 FROM OPENQUERY 
                       ([NameOfLinkedSERVER], 
                       'SELECT field1 FROM TABLENAME') 
                               WHERE field1=@someParameter T1 
                                     INNER JOIN MYSQLSERVER.DATABASE.DBO.TABLENAME           
                                     T2 ON T1.PK = T2.PK
    
  7. ==============================

    7.OpenQuery를 함께 동적 SQL을 결합합니다. (이것은 테라 데이타 서버로 이동)

    OpenQuery를 함께 동적 SQL을 결합합니다. (이것은 테라 데이타 서버로 이동)

    DECLARE 
        @dayOfWk    TINYINT = DATEPART(DW, GETDATE()),
        @qSQL       NVARCHAR(MAX) = '';
    
    SET @qSQL = '
    SELECT
        *
    FROM
        OPENQUERY(TERASERVER,''
            SELECT DISTINCT
                CASE
                    WHEN ' + CAST(@dayOfWk AS NCHAR(1)) + ' = 2
                    THEN ''''Monday''''
                    ELSE ''''Not Monday''''
                END
            '');';
    
    EXEC sp_executesql @qSQL;
    
  8. ==============================

    8.다음 예에서 내가 저장 프로 시저 (spIncreaseTotalsRpt)에 부서 매개 변수를 전달하고있어 같은 시간에 나는 전혀 OPENQUERY에서 임시 테이블을 만드는거야. 그것은 그것의 intance 외부에서 참조 할 수 있도록 임시 테이블의 요구는 글로벌 온도 (##)이 될 수 있습니다. 간부 sp_executesql을을 사용하여 당신은 부서 매개 변수를 전달할 수 있습니다.

    다음 예에서 내가 저장 프로 시저 (spIncreaseTotalsRpt)에 부서 매개 변수를 전달하고있어 같은 시간에 나는 전혀 OPENQUERY에서 임시 테이블을 만드는거야. 그것은 그것의 intance 외부에서 참조 할 수 있도록 임시 테이블의 요구는 글로벌 온도 (##)이 될 수 있습니다. 간부 sp_executesql을을 사용하여 당신은 부서 매개 변수를 전달할 수 있습니다.

    참고 : sp_executesql을 사용시주의하십시오. 또한 관리자는 사용 가능한이 옵션이 없을 수 있습니다.

    이 사람을 도움이되기를 바랍니다.

     IF OBJECT_ID('tempdb..##Temp') IS NOT NULL
    /*Then it exists*/
        begin
           DROP TABLE ##Temp
        end 
     Declare @Dept as nvarchar(20) ='''47'''
    
     declare @OPENQUERY  as nvarchar(max)
    set @OPENQUERY = 'Select ' + @Dept + ' AS Dept,  * into ##Temp from openquery(SQL_AWSPROD01,''' 
    
    declare @sql nvarchar(max)= @openquery +  'SET FMTONLY OFF EXECUTE SalaryCompensation.dbo.spIncreaseTotalsRpts ' + '''' + @Dept + ''''  + ''')'
    declare @parmdef nvarchar(25) 
    DECLARE @param nvarchar(20) 
    
    SET @parmdef = N'@Dept varchar(20)'
    -- select @sql
    -- Print @sql + @parmdef  + @dept
    exec sp_executesql @sql,@parmdef, @Dept  
    Select * from ##Temp
    

    결과

    부서 증가에서 Cnt 0 1 2 3 4 5 6         0.0000 1.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000

  9. ==============================

    9.나는 나를 위해 작동하는 방법을 알아 냈어. 그것은 연결된 서버 그래도에 액세스 할 수 있는지 스크래치 테이블의 사용을 필요로한다.

    나는 나를 위해 작동하는 방법을 알아 냈어. 그것은 연결된 서버 그래도에 액세스 할 수 있는지 스크래치 테이블의 사용을 필요로한다.

    나는 테이블을 생성하고 내가 연결된 서버를 통해 해당 테이블을 참조하는 다음 필요한 값을 채워집니다.

    SELECT * 
    FROM OPENQUERY(KHSSQLODSPRD,'SELECT *
      FROM ABC.dbo.CLAIM A WITH (NOLOCK)
      WHERE A.DOS >= (SELECT MAX(DATE) FROM KHSDASQL01.DA_MAIN.[dbo].[ALLFILENAMES]) ')
    
  10. ==============================

    10.간단한 예는 @Tuan 자이의 예를의 기반으로하는보다 쉬운 것 같았다. 당신이 ... OPENQUERY의 외부에 필터를 할 수있는 너무 쉽게 몰랐어요!

    간단한 예는 @Tuan 자이의 예를의 기반으로하는보다 쉬운 것 같았다. 당신이 ... OPENQUERY의 외부에 필터를 할 수있는 너무 쉽게 몰랐어요!

    그러나 내 경우에는 내가 단일 값을 반환 할 추가 하위 쿼리 레벨을 생성하도록 변수에 물건을 할 필요가 있었다.

    SET @SFID = (SELECT T.Id FROM (SELECT Id,  Contact_ID_SQL__c  FROM OPENQUERY([TR-SF-PROD], 'SELECT Id,  Contact_ID_SQL__c FROM Contact') WHERE Contact_ID_SQL__c = @ContactID) T)
    
  11. ==============================

    11.

    declare @p_Id varchar(10)
    SET @p_Id = '40381'
    
    EXECUTE ('BEGIN update TableName
                    set     ColumnName1 = null,
                            ColumnName2 = null,
                            ColumnName3 = null,
                            ColumnName4 = null
                     where   PERSONID = '+ @p_Id +'; END;') AT [linked_Server_Name]
    
  12. from https://stackoverflow.com/questions/3378496/including-parameters-in-openquery by cc-by-sa and MIT license