복붙노트

[SQL] X SELECT * FROM WHERE 단정 한 ORM과 아이디 IN (...)

SQL

X SELECT * FROM WHERE 단정 한 ORM과 아이디 IN (...)

IN 절 값 목록은 비즈니스 로직에서 오는 경우 단정 한 ORM을 사용하여 절이있는 쿼리를 작성하는 가장 좋은 방법은 무엇입니까? 예를 들어 보자의 내가 쿼리가 있다고 가정 :

SELECT * 
  FROM SomeTable 
 WHERE id IN (commaSeparatedListOfIDs)

commaSeparatedListOfIDs 비즈니스 로직에 전달되는 그것은 (정수의)는 IEnumerable의 모든 유형이 될 수 있습니다. 어떻게이 경우 쿼리를 만들 것인가? 나는 내가 지금까지 기본적으로 문자열 연결 또는 내가 알고 아니에요 고급 매개 변수 매핑 기술의 일종이있는 뭘했는지 어떻게해야합니까?

해결법

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

    1.단정은 직접 지원합니다. 예를 들어 ...

    단정은 직접 지원합니다. 예를 들어 ...

    string sql = "SELECT * FROM SomeTable WHERE id IN @ids"
    var results = conn.Query(sql, new { ids = new[] { 1, 2, 3, 4, 5 }});
    
  2. ==============================

    2.직접 GitHub의 프로젝트 홈페이지에서 :

    직접 GitHub의 프로젝트 홈페이지에서 :

    connection.Query<int>(
        @"select * 
          from (select 1 as Id union all select 2 union all select 3) as X 
          where Id in @Ids", 
        new { Ids = new int[] { 1, 2, 3 });
    

    에 번역 될 것이다 :

    select * 
    from (select 1 as Id union all select 2 union all select 3) as X 
    where Id in (@Ids1, @Ids2, @Ids3)
    
    // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3
    
  3. ==============================

    3.당신의 IN 절은 MSSQL 처리하기에 너무 큰 경우에, 당신은 아주 쉽게 단정하여 매개 변수 값을 갖는 테이블을 사용할 수 있습니다.

    당신의 IN 절은 MSSQL 처리하기에 너무 큰 경우에, 당신은 아주 쉽게 단정하여 매개 변수 값을 갖는 테이블을 사용할 수 있습니다.

    단순히 TVP를 구축하고 TVP에 가입 내부에 업데이 트를 할 수 - 여러 컬럼의 질량 업데이트를 수행 할 때 또한 환상적으로 작동합니다.

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

    4.여기 가능성이 말끔이 ID 목록을 사용하여 많은 수의 행을 조회 할 수있는 가장 빠른 방법입니다. 나는 이것이 내가 테스트하지 않은 어떤 빨리 당신이 다른 답변에 주어진 같은 TVP를 사용 가능한 제외 (생각할 수있는 거의 모든 다른 방법보다, 당신을 약속하지만 여전히 채울 수 있기 때문에 나는 느려질 수 있습니다 의심 TVP). 그것은 행성 빠르고 말끔이 IN 구문과 빠른 행에 의해 엔티티 프레임 워크의 행보다 우주를 사용하는 것보다. 그리고 더 빠른 값이나 UNION ALL SELECT 항목의 목록을 전달보다는 대륙된다. 쉽게 그냥 DataTable을, 임시 테이블에 여분의 열을 추가, 멀티 컬럼 키를 사용하도록 확장하고, 조건에 가입 할 수 있습니다.

    여기 가능성이 말끔이 ID 목록을 사용하여 많은 수의 행을 조회 할 수있는 가장 빠른 방법입니다. 나는 이것이 내가 테스트하지 않은 어떤 빨리 당신이 다른 답변에 주어진 같은 TVP를 사용 가능한 제외 (생각할 수있는 거의 모든 다른 방법보다, 당신을 약속하지만 여전히 채울 수 있기 때문에 나는 느려질 수 있습니다 의심 TVP). 그것은 행성 빠르고 말끔이 IN 구문과 빠른 행에 의해 엔티티 프레임 워크의 행보다 우주를 사용하는 것보다. 그리고 더 빠른 값이나 UNION ALL SELECT 항목의 목록을 전달보다는 대륙된다. 쉽게 그냥 DataTable을, 임시 테이블에 여분의 열을 추가, 멀티 컬럼 키를 사용하도록 확장하고, 조건에 가입 할 수 있습니다.

    public IReadOnlyCollection<Item> GetItemsByItemIds(IEnumerable<int> items) {
       var itemList = new HashSet(items);
       if (itemList.Count == 0) { return Enumerable.Empty<Item>().ToList().AsReadOnly(); }
    
       var itemDataTable = new DataTable();
       itemDataTable.Columns.Add("ItemId", typeof(int));
       itemList.ForEach(itemid => itemDataTable.Rows.Add(itemid));
    
       using (SqlConnection conn = GetConnection()) // however you get a connection
       using (var transaction = conn.BeginTransaction()) {
          conn.Execute(
             "CREATE TABLE #Items (ItemId int NOT NULL PRIMARY KEY CLUSTERED);",
             transaction: transaction
          );
    
          new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, transaction) {
             DestinationTableName = "#Items",
             BulkCopyTimeout = 3600 // ridiculously large
          }
             .WriteToServer(itemDataTable);
          var result = conn
             .Query<Item>(@"
                SELECT i.ItemId, i.ItemName
                FROM #Items x INNER JOIN dbo.Items i ON x.ItemId = i.ItemId
                DROP TABLE #Items;",
                transaction: transaction,
                commandTimeout: 3600
             )
             .ToList()
             .AsReadOnly();
          transaction.Rollback(); // Or commit if you like
          return result;
       }
    }
    

    당신이 대량 삽입에 대해 조금 배울 필요가 있음을 알고 있어야합니다. 제약을 존중, (기본값은 '아니오') 트리거를 발사 테이블 잠금, 동시 삽입을 허용, 등등에 대한 옵션이 있습니다.

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

    5.또한 당신이 지금처럼 쿼리 문자열을 괄호로 포장하지합니다

    또한 당신이 지금처럼 쿼리 문자열을 괄호로 포장하지합니다

    SELECT Name from [USER] WHERE [UserId] in (@ids)
    

    나는 괄호를 제거하여 고정 단정 1.50.2 사용하여 SQL 구문 오류를,이 원인을했다

    SELECT Name from [USER] WHERE [UserId] in @ids
    
  6. ==============================

    6.우리가 일반 SQL에서와 WHERE 절에 ()를 추가 할 필요가 없습니다. 단정은 우리를 위해 자동으로 해당 작업을 수행하기 때문에. 다음 구문은 다음과 같습니다 -

    우리가 일반 SQL에서와 WHERE 절에 ()를 추가 할 필요가 없습니다. 단정은 우리를 위해 자동으로 해당 작업을 수행하기 때문에. 다음 구문은 다음과 같습니다 -

    const string SQL = "SELECT IntegerColumn, StringColumn FROM SomeTable WHERE IntegerColumn IN @listOfIntegers";
    
    var conditions = new { listOfIntegers };
    
    var results = connection.Query(SQL, conditions);
    
  7. ==============================

    7.포스트 그레스에 대한 예 :

    포스트 그레스에 대한 예 :

    string sql = "SELECT * FROM SomeTable WHERE id = ANY(@ids)"
    var results = conn.Query(sql, new { ids = new[] { 1, 2, 3, 4, 5 }});
    
  8. ==============================

    8.내 경우에는 내가 이것을 사용했습니다 :

    내 경우에는 내가 이것을 사용했습니다 :

    var query = "select * from table where Id IN @Ids";
    var result = conn.Query<MyEntity>(query, new { Ids = ids });
    

    두 번째 줄에 내 변수 "IDS는"문자열의는 IEnumerable입니다, 또한 내가 추측 정수가 될 수 있습니다.

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

    9.내 경험에 의하면,이 다루는 가장 쉬운 방법은 값의 테이블에 문자열을 변환하는 기능을 가지고있다.

    내 경험에 의하면,이 다루는 가장 쉬운 방법은 값의 테이블에 문자열을 변환하는 기능을 가지고있다.

    웹에서 사용할 수 많은 스플리터 기능이 있습니다, 당신은 쉽게 하나를 찾을 수 있습니다 어떤 SQL 당신의 맛 경우.

    당신은 할 수 있습니다 ...

    SELECT * FROM table WHERE id IN (SELECT id FROM split(@list_of_ids))
    

    또는

    SELECT * FROM table INNER JOIN (SELECT id FROM split(@list_of_ids)) AS list ON list.id = table.id
    

    (또는 유사)

  10. from https://stackoverflow.com/questions/8388093/select-from-x-where-id-in-with-dapper-orm by cc-by-sa and MIT license