복붙노트

[SQL] C # SQL 서버 - 저장 프로 시저 목록을 전달

SQL

C # SQL 서버 - 저장 프로 시저 목록을 전달

내 C # 코드에서 SQL Server 저장 프로 시저를 호출하고 있습니다 :

using (SqlConnection conn = new SqlConnection(connstring))
{
   conn.Open();
   using (SqlCommand cmd = new SqlCommand("InsertQuerySPROC", conn))
   {
      cmd.CommandType = CommandType.StoredProcedure;

      var STableParameter = cmd.Parameters.AddWithValue("@QueryTable", QueryTable);
      var NDistanceParameter = cmd.Parameters.AddWithValue("@NDistanceThreshold", NDistanceThreshold);
      var RDistanceParameter = cmd.Parameters.AddWithValue(@"RDistanceThreshold", RDistanceThreshold);

      STableParameter .SqlDbType = SqlDbType.Structured;
      NDistanceParameter.SqlDbType = SqlDbType.Int;
      RDistanceParameter.SqlDbType = SqlDbType.Int;

      // Execute the query
      SqlDataReader QueryReader = cmd.ExecuteReader();

내 저장된 프로 시저는 매우 표준이지만이 (저장 시저를 사용하는을위한 따라서 필요) 쿼리 테이블에 참여한다.

지금 : 나는 문자열 목록을 추가하려면, 목록 <문자열>, 매개 변수 세트. 예를 들어, 내 저장된 프로 시저 쿼리는 다음과 같이 간다 :

SELECT feature 
FROM table1 t1 
INNER JOIN @QueryTable t2 ON t1.fid = t2.fid 
WHERE title IN <LIST_OF_STRINGS_GOES_HERE>

그러나, 문자열의 목록은 동적이며 긴 몇 백.

저장된 proc 디렉토리에 문자열 목록 <문자열>의 목록을 전달하는 방법이 있나요 ??? 또는이 할 수있는 더 좋은 방법은 무엇입니까?

많은 감사합니다, 브렛

해결법

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

    1.당신은 SQL 서버 2008을 사용하는 경우, 테이블 타입 정의 새로운 기능을 갖춘라는 사용자가있다. 여기를 사용하는 방법의 예입니다 :

    당신은 SQL 서버 2008을 사용하는 경우, 테이블 타입 정의 새로운 기능을 갖춘라는 사용자가있다. 여기를 사용하는 방법의 예입니다 :

    표 유형 정의하여 사용자 만들기 :

    CREATE TYPE [dbo].[StringList] AS TABLE(
        [Item] [NVARCHAR](MAX) NULL
    );
    

    다음 당신은 당신의 저장 프로 시저에 적절하게 사용해야합니다 :

    CREATE PROCEDURE [dbo].[sp_UseStringList]
        @list StringList READONLY
    AS
    BEGIN
        -- Just return the items we passed in
        SELECT l.Item FROM @list l;
    END
    

    마지막으로 여기에 C #에서 사용하는 몇 가지 SQL이다 :

    using (var con = new SqlConnection(connstring))
    {
        con.Open();
    
        using (SqlCommand cmd = new SqlCommand("exec sp_UseStringList @list", con))
        {
            using (var table = new DataTable()) {
              table.Columns.Add("Item", typeof(string));
    
              for (int i = 0; i < 10; i++)
                table.Rows.Add("Item " + i.ToString());
    
              var pList = new SqlParameter("@list", SqlDbType.Structured);
              pList.TypeName = "dbo.StringList";
              pList.Value = table;
    
              cmd.Parameters.Add(pList);
    
              using (var dr = cmd.ExecuteReader())
              {
                while (dr.Read())
                    Console.WriteLine(dr["Item"].ToString());
              }
             }
        }
    }
    

    SSMS에서이 작업을 실행하려면

    DECLARE @list AS StringList
    
    INSERT INTO @list VALUES ('Apple')
    INSERT INTO @list VALUES ('Banana')
    INSERT INTO @list VALUES ('Orange')
    
    -- Alternatively, you can populate @list with an INSERT-SELECT
    INSERT INTO @list
       SELECT Name FROM Fruits
    
    EXEC sp_UseStringList @list
    
  2. ==============================

    2.이 상황에서 일반적인 패턴은 쉼표로 구분 된 목록의 요소를 전달하는 것입니다, 다음 SQL에서 사용할 수있는 테이블에 저를 분할합니다. 대부분의 사람들은 보통처럼이 일을 위해 지정된 함수를 만들 :

    이 상황에서 일반적인 패턴은 쉼표로 구분 된 목록의 요소를 전달하는 것입니다, 다음 SQL에서 사용할 수있는 테이블에 저를 분할합니다. 대부분의 사람들은 보통처럼이 일을 위해 지정된 함수를 만들 :

     INSERT INTO <SomeTempTable>
     SELECT item FROM dbo.SplitCommaString(@myParameter)
    

    그리고 당신은 다른 쿼리에서 사용할 수 있습니다.

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

    3.아니, 배열 / 목록은 직접 SQL Server로 전달 될 수 없습니다.

    아니, 배열 / 목록은 직접 SQL Server로 전달 될 수 없습니다.

    다음 옵션을 사용할 수 있습니다 :

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

    4.그래, VARCHAR와 같은 메이크업 저장된 프로 시저 매개 변수 (...) 다음 프로 시저에 콤마 분리 된 값을 전달한다.

    그래, VARCHAR와 같은 메이크업 저장된 프로 시저 매개 변수 (...) 다음 프로 시저에 콤마 분리 된 값을 전달한다.

    문자열의 배열보다 더 복잡한 쿼리 테이블의 구조가 그렇지 않으면 잔인한 될 경우 SQL Server 내에서 생성 할 테이블 유형을 필요로하기 때문에 SQL 2008 TVP 및 LINQ : 당신의 SQL 서버 2008을 사용하는 경우에 당신은 TVP (표 값 매개 변수)를 활용할 수 있습니다

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

    5.대신 목록 중 하나 열이있는 데이터 테이블을 만들고 테이블에 문자열을 추가합니다. 당신은 구조화 된 유형으로이 데이터 테이블을 전달하고 또 다른 테이블의 제목 필드에 가입 수행 할 수 있습니다.

    대신 목록 중 하나 열이있는 데이터 테이블을 만들고 테이블에 문자열을 추가합니다. 당신은 구조화 된 유형으로이 데이터 테이블을 전달하고 또 다른 테이블의 제목 필드에 가입 수행 할 수 있습니다.

  6. ==============================

    6.당신은 SQL에서 분할에게 CSV 목록을 선호하는 경우, 일반 테이블 식 (CTE를)를 사용하여 그것을 할 수있는 다른 방법이있다. CTE를 사용하여 문자열 분할에 효율적인 방법을 참조하십시오.

    당신은 SQL에서 분할에게 CSV 목록을 선호하는 경우, 일반 테이블 식 (CTE를)를 사용하여 그것을 할 수있는 다른 방법이있다. CTE를 사용하여 문자열 분할에 효율적인 방법을 참조하십시오.

  7. ==============================

    7.내가 CSV 목록을 구축하고 문자열로 통과 알고 있어요 유일한 방법. 그런 다음, SP 측에, 그냥 분할 당신이 필요로하는 무엇이든.

    내가 CSV 목록을 구축하고 문자열로 통과 알고 있어요 유일한 방법. 그런 다음, SP 측에, 그냥 분할 당신이 필요로하는 무엇이든.

  8. ==============================

    8.

    CREATE TYPE [dbo].[StringList1] AS TABLE(
    [Item] [NVARCHAR](MAX) NULL,
    [counts][nvarchar](20) NULL);
    

    테이블로 유형을 생성하고 "StringList1"로 이름을

    create PROCEDURE [dbo].[sp_UseStringList1]
    @list StringList1 READONLY
    AS
    BEGIN
        -- Just return the items we passed in
        SELECT l.item,l.counts FROM @list l;
        SELECT l.item,l.counts into tempTable FROM @list l;
     End
    

    위의 같은 프로 시저를 작성하고 "UserStringList1"로 이름을  에스

    String strConnection = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString.ToString();
                SqlConnection con = new SqlConnection(strConnection);
                con.Open();
                var table = new DataTable();
    
                table.Columns.Add("Item", typeof(string));
                table.Columns.Add("count", typeof(string));
    
                for (int i = 0; i < 10; i++)
                {
                    table.Rows.Add(i.ToString(), (i+i).ToString());
    
                }
                    SqlCommand cmd = new SqlCommand("exec sp_UseStringList1 @list", con);
    
    
                        var pList = new SqlParameter("@list", SqlDbType.Structured);
                        pList.TypeName = "dbo.StringList1";
                        pList.Value = table;
    
                        cmd.Parameters.Add(pList);
                        string result = string.Empty;
                        string counts = string.Empty;
                        var dr = cmd.ExecuteReader();
    
                        while (dr.Read())
                        {
                            result += dr["Item"].ToString();
                            counts += dr["counts"].ToString();
                        }
    

    는 C #,이 시도

  9. from https://stackoverflow.com/questions/7097079/c-sharp-sql-server-passing-a-list-to-a-stored-procedure by cc-by-sa and MIT license