복붙노트

[SQL] 다른 데이터베이스에서 쿼리의 결과에 따라 데이터베이스 쿼리

SQL

다른 데이터베이스에서 쿼리의 결과에 따라 데이터베이스 쿼리

나는 VS 2013 년 SSIS를 사용하고 있습니다. 나는 한 데이터베이스에서 ID의 목록을 얻을 필요가 있고, ID의 그 목록에, 나는 MySecondDB에서 ... 다른 데이터베이스, 즉 SELECT를 조회 할 WHERE ID IN ({MyFirstDB에서 ID의 목록}).

해결법

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

    1.이를 달성하기 위해 3 개 가지 방법이 있습니다 :

    이를 달성하기 위해 3 개 가지 방법이 있습니다 :

    @TheEsisia 대답하지만 더 요구 사항이있는 것처럼 먼저 당신은 조회 변환을 추가해야합니다 :

    필터 행 WHERE ID IN ({MyFirstDB에서 ID의 목록})는 2 가지 방법이 있습니다 오류 출력 오류의 경우 최대 모양에서 몇 가지 작업을 수행해야합니다 :

    당신이 유사한 표현을 사용할 필요가 있도록 조회 열로 COL1을 선택했다고 가정

    ISNULL([col1]) == False
    

    이 방법의 단점은 모든 데이터가로드되어 실행 중에 여과된다는 것이다.

    네트워크 필터링 작업을하는 것은 모든 데이터가로드 된 후에 로컬 컴퓨터 (서버 2 방법)에서 수행되는 경우에도 메모리이다.

    모든 데이터를로드 방지하려면 해결 방법을 수행 할 수 있습니다, 당신은 스크립트 작업을 사용하여이를 얻을 수 있습니다 : (대답은 VB.NET에 writen)

    연결 관리자의 이름이 "dbo.MyTable에서 선택 [ID]"TestAdo하고 있다는 질의를한다 가정하면 ID의 목록을 얻고, 사용하기 :: MyVariableList는 아이디의 목록을 저장할 변수입니다

    참고 :이 코드는 연결 관리자에서 연결을 읽

        Public Sub Main()
    
            Dim lst As New Collections.Generic.List(Of String)
    
    
            Dim myADONETConnection As SqlClient.SqlConnection  
        myADONETConnection = _  
            DirectCast(Dts.Connections("TestAdo").AcquireConnection(Dts.Transaction), _  
            SqlClient.SqlConnection)
    
            If myADONETConnection.State = ConnectionState.Closed Then
            myADONETConnection.Open()
            End If
    
            Dim myADONETCommand As New SqlClient.SqlCommand("Select [ID] FROM dbo.MyTable", myADONETConnection)
    
            Dim dr As SqlClient.SqlDataReader
    
            dr = myADONETCommand.ExecuteReader
    
            While dr.Read
    
                lst.Add(dr(0).ToString)
    
            End While
    
    
            Dts.Variables.Item("User::MyVariableList").Value = "SELECT ... FROM ... WHERE ID IN(" &  String.Join(",", lst) & ")"
    
            Dts.TaskResult = ScriptResults.Success
        End Sub
    

    그리고 사용자 :: MyVariableList 소스로 사용한다 (SQL 변수에 명령)

    두 번째 방법과 유사하지만이 후 OLEDB 소스로 전체 쿼리를 사용하여 SQL 실행 태스크를 사용하여 IN 절을 구축 할 것입니다,

    열이 문자열 데이터 유형이있는 경우에 당신은 전에 아래와 같이 값을 후 견적을 추가해야합니다 :

    SELECT @str = @str + '''' + CAST([ID] AS VARCHAR(255)) + ''','
        FROM dbo.MyTable
    

    당신이 True로 데이터 흐름 작업 지연 검증 속성을 설정했는지 확인

  2. ==============================

    2.이는 조회 변환을 사용하는 전형적인 경우이다. 먼저, 첫 번째 데이터베이스에서 데이터를 얻을 수있는 OLE DB 원본을 사용합니다. 그리고, 제 2 데이터 세트의 ID 값에 기초하여이 데이터 세트를 필터링하는 조회 변환을 사용한다. 여기 조회 변환을 사용하는 단계이다 :

    이는 조회 변환을 사용하는 전형적인 경우이다. 먼저, 첫 번째 데이터베이스에서 데이터를 얻을 수있는 OLE DB 원본을 사용합니다. 그리고, 제 2 데이터 세트의 ID 값에 기초하여이 데이터 세트를 필터링하는 조회 변환을 사용한다. 여기 조회 변환을 사용하는 단계이다 :

    일반 설정

    연결:

    ID 열을 일치 :

    일치 출력 :

  3. ==============================

    3.내가 먼저 예를 들어, String 변수를 만들 것 SQL_Select, 패키지의 범위에서. 그럼 값이 제 1 회 데이터베이스에 대해 SQL 실행 태스크를 사용하여 해당 할당합니다. 일반 페이지에서 결과 집합 속성은 단일 행으로 설정해야합니다. 당신의 변수에 할당하는 결과 설정 탭에 항목을 추가합니다.

    내가 먼저 예를 들어, String 변수를 만들 것 SQL_Select, 패키지의 범위에서. 그럼 값이 제 1 회 데이터베이스에 대해 SQL 실행 태스크를 사용하여 해당 할당합니다. 일반 페이지에서 결과 집합 속성은 단일 행으로 설정해야합니다. 당신의 변수에 할당하는 결과 설정 탭에 항목을 추가합니다.

    SQL 문 사용 요구는 텍스트의 단일 행에, 당신의 2 데이터베이스에 필요한 SELECT 문을 반환하도록 설계된다. 예는 다음과 같습니다

    SELECT 
        'SELECT * from MySecondDB WHERE ID IN ( ' 
        + STUFF ( (
            SELECT TOP 5
                ' , ''' + [name] + ''''
            FROM  dbo.spt_values
            FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(4000)'                
            ) , 1 , 3, '' ) 
        + ' ) '
        AS SQL_Select
    

    상위 5 개를 제거하고 [이름]과 열 및 테이블 이름 dbo.spt_values를 교체합니다.

    그럼 당신은 예를 들어, 다운 스트림 작업에서 변수 SQL_Select을 사용할 수 있습니다 는 OLE DB 원본 데이터베이스 2. OLE DB 소스 및 OLE DB 명령 작업에 대해 사용자가 SQL 소스로 변수를 지정할 수 있습니다 둘.

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

    4."최고"대답은 관련 데이터 볼륨과 소스 시스템에 따라 달라집니다.

    "최고"대답은 관련 데이터 볼륨과 소스 시스템에 따라 달라집니다.

    다른 답변의 대부분은 SQL Server 내 영리 연결을 기반으로 값 목록을 구축 제안한다. 즉, 잘 참조 시스템 인 경우 작동하지 않습니다 오라클, MySQL은, DB2는, 인포믹스, 포스트 그레스 등 상응하는 개념이있을 수 있지만이되지 않을 수 있습니다.

    최적의 성능을 위해, 당신은 이제까지 데이터 흐름에 충돌하는 행의 전에 두 번째 DB에 대한 필터가 필요합니다. 다른 사람이 소스 쿼리에 제안대로 것을 의미는 필터링 조건을 추가. 이 접근 방식의 문제는 쿼리는 내가 기억하지 않는 것이 몇 가지 구체적인 범위에 의해 제한 될 예정이다. 십, 백, 절은 아마 괜찮 귀하의 경우에 만 개 값. 라크, 만 - 아마 너무 많이.

    소스 테이블에 대한 필터 값의 큰 볼륨을 가지고있는 경우에, 테이블 (SQL 작업 + 데이터 흐름 실행)하는 것이 해당 서버 및 잘라 내기 및 재 장전에 테이블을 생성하는 것이 할 수 있습니다. 이것은 당신이 지역의 모든 데이터를 가지고 한 다음 인덱스 필터 테이블과 데이터베이스 엔진은 정말 좋은 일을 할 수 있습니다.

    .이 최대 봐 : 그러나, 당신은 소스 데이터베이스가 당신이 테이블을 만들 수없는 일부 사용자 지정 솔루션이라고 임시 테이블 위의 접근 방식에서 볼 수 있으며 SSIS에서 방금 싱글로 연결을 표시해야합니다 / TODO (지속 ). 내가 그들을 디버깅 등의 SSIS와 임시 테이블에 대해별로주의 할 것은 내 운명 적에 소원을하지 않는 게 좋을 악몽이다.

    당신이 아직도 읽고있는 경우에, 우리는 소스 시스템에서 필터링하는 것이 최상의 성능을 제공 할 것입니다 경우에도 "행할"수없는 이유를 확인했습니다.

    이제 우리는 순수 SSIS 솔루션과 붙어있어. 최상의 성능을 얻으려면, 드롭 다운 메뉴에서 테이블 이름을 선택하지 않는다 - 당신이 절대적으로 모든 열을 필요로하지 않는. 또한, 데이터 유형에주의를 기울이십시오. 데이터 흐름에 LOB 당기 (XML, 텍스트, 이미지 (N) VARCHAR (최대), VARBINARY (최대))는 나쁜 성능을위한 조리법이다.

    기본 제안은 데이터 흐름에서 데이터를 필터링하는 조회 부품을 사용하는 것이다. 긴 소스 시스템 지원 및 OLE DB 공급자로 (또는 당신은 캐시 연결 관리자에 데이터를 강요 할 수 있습니다)

    당신이 어떤 이유로 조회 구성 요소를 사용할 수없는 경우에만 초래하는 흐름 당신은 명시 적으로 분류 소스 시스템에서 데이터는 같은 소스 구성 요소를 표시 할 수 있습니다, 다음 병합이 내부 데이터에 가입 유형 가입 사용 유사한 데이터.

    그러나 소스 시스템의 종류는 기본 규칙에 따라 정렬 할려고하고 있다는 것을주의해야합니다. 나는 EBCDIC 종류를 제공하는 SQL Server가 ZOS에서 실행되는 기본 ASCII 정렬 내 DB2 인스턴스에 따라 정렬이 된 상황에 달렸다. 어떤 내 도메인은 정수했지만 키가 숫자가되었다 때 handbasket에서 지옥에 갔다 (AAA, A2B, 그리고 AZZ이 종류의 다른이를 기반으로합니다) 때 좋았어요.

    마지막으로, 마지막 단락을 제외한 위는 정수를 가정합니다. 당신이 문자열 일치를 수행하는 경우 다른 구성 요소 또는 (또한 요소가 될 수 있습니다 대소 문자를 구분 시스템과 정렬) 경우 구분 일치를 수행하지 않을 수 있기 때문에, 당신은 추의 추가 레벨을 얻을.

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

    5.당신은 두 서버간에 연결된 서버를 추가 할 수 있습니다. SQL 명령은 다음과 같이 될 것이다 :

    당신은 두 서버간에 연결된 서버를 추가 할 수 있습니다. SQL 명령은 다음과 같이 될 것이다 :

    EXEC sp_addlinkedserver @server='SRV' --or any name you want
    EXEC sp_addlinkedsrvlogin 'SRV', 'false', null, 'username', 'password'
    
    SELECT * FROM SRV.CatalogNameInSecondDB.dbo.SecondDBTableName s
    INNER JOIN FirstDBTableName f on s.ID = f.ID
    WHERE f.ID IN (list of values)
    
    EXEC sp_dropserver 'SRV', 'droplogins'
    
  6. from https://stackoverflow.com/questions/43746258/query-a-database-based-on-result-of-query-from-another-database by cc-by-sa and MIT license