Parameters to the EXISTS clause in a stored procedure

后端 未结 1 729
傲寒
傲寒 2020-12-20 07:56

I have a table DEPT, which holds 2 columns - ID, NAME.

A search form is presented with the IDs from the DEPT table and the use

相关标签:
1条回答
  • 2020-12-20 08:40
    CREATE TYPE dbo.DeptList
    AS TABLE
    (
      ID INT
    );
    GO
    
    CREATE PROCEDURE dbo.RetrieveDepartments
      @dept_list AS dbo.DeptList READONLY
    AS
    BEGIN
      SET NOCOUNT ON;
    
      SELECT Name FROM dbo.table1 WHERE ID IN (SELECT ID FROM @dept)
      UNION ALL 
      SELECT Name FROM dbo.table2 WHERE ID IN (SELECT ID FROM @dept)
      -- ...
    END
    GO
    

    Now in your C# code, create a DataTable, fill it in with the IDs, and pass it in to the stored procedure. Assuming you already have a list called tempList and the IDs are stored in id:

    DataTable tvp = new DataTable();
    tvp.Columns.Add(new DataColumn("ID"));
    
    foreach(var item in tempList)
    { 
        tvp.Rows.Add(item.id); 
    }
    
    using (connObject)
    {
        SqlCommand cmd = new SqlCommand("StoredProcedure", connObject);
        cmd.CommandType = CommandType.StoredProcedure;
        SqlParameter tvparam = cmd.Parameters.AddWithValue("@dept_list", tvp);
        tvparam.SqlDbType = SqlDbType.Structured;
        ...
    }
    

    You can also use a split function. Many exist, this is the one I like if you can guarantee that the input is safe (no <, >, & etc.):

    CREATE FUNCTION dbo.SplitInts_XML
    (
       @List       VARCHAR(MAX),
       @Delimiter  CHAR(1)
    )
    RETURNS TABLE
    AS
       RETURN 
       (  
          SELECT Item = y.i.value('(./text())[1]', 'int')
          FROM 
          ( 
            SELECT x = CONVERT(XML, '<i>' 
            + REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.')
          ) AS a 
          CROSS APPLY x.nodes('i') AS y(i)
       );
    GO
    

    Now your procedure can be:

    CREATE PROCEDURE dbo.RetrieveDepartments
      @dept_list VARCHAR(MAX)
    AS
    BEGIN
      SET NOCOUNT ON;
    
      ;WITH d AS (SELECT ID = Item FROM dbo.SplitInts(@dept_list, ','))
      SELECT Name FROM dbo.table1 WHERE ID IN (SELECT ID FROM d)
      UNION ALL
      SELECT Name FROM dbo.table2 WHERE ID IN (SELECT ID FROM d)
      -- ...
    END
    GO
    
    0 讨论(0)
提交回复
热议问题