2011-11-16 47 views
0

鉴于这种精确即席查询:如何使用ADO.NET执行此SQL查询?

DECLARE @list AS TABLE (Name VARCHAR(20)) 
INSERT INTO @list(Name) 
VALUES ('Otter', 'Lebron', 'Aaron', 'Brock') 

SELECT * 
FROM Users 
WHERE FirstName in (SELECT Name from @list) 

这又如何使用C#ADO.NET用的SqlParameter做什么?

+1

你真的需要做表变量的单个值,或者这是一个过于简单化?换句话说,为什么2+语句而不是1?什么是参数? –

+0

这个例子过于简化,编辑起来更有意义。 –

+0

该列表来自ADO.NET端,DataTable或字符串的参数是什么类型? – Icarus

回答

4

我对示例目的使用了原始SQL的修改。

DECLARE @list AS TABLE (Name VARCHAR(20)); 
INSERT INTO @list(Name) 
VALUES ('PROCEDURE'), 
     ('FUNCTION'); 

SELECT * 
FROM INFORMATION_SCHEMA.ROUTINES 
WHERE ROUTINE_TYPE in (SELECT Name from @list) 

您可以使用表值参数

下面是Table-Valued Parameters in SQL Server 2008 (ADO.NET)

 using (SqlConnection cnn = new SqlConnection("Your connection string")) 
     { 

      var tableParam = new DataTable("names"); 
      tableParam.Columns.Add("Name", typeof(string)); 
      tableParam.Rows.Add(new object[] { "PROCEDURE" }); 
      tableParam.Rows.Add(new object[] { "FUNCTION')" }); 

      var sql = @"DECLARE @list AS TABLE (Name VARCHAR(20)) 
         INSERT INTO @list(Name) 
         SELECT Name from @Names; 

         SELECT * 
         FROM INFORMATION_SCHEMA.ROUTINES 
         WHERE ROUTINE_TYPE in (SELECT Name from @list)"; 

      var sqlCmd = new SqlCommand(sql, cnn); 
      var tvpParam = sqlCmd.Parameters.AddWithValue("@Names", tableParam); 
      tvpParam.SqlDbType = SqlDbType.Structured; 
      tvpParam.TypeName = "dbo.Names"; 

      cnn.Open(); 
      using(SqlDataReader rdr = sqlCmd.ExecuteReader()) 
      { 
       while (rdr.Read()) 
        Console.WriteLine(rdr["SPECIFIC_NAME"]);      

      } 



     } 

采取修改示例但你需要定义类型dbo.Names它可以工作

这里是创建类型SQL

CREATE TYPE dbo.Names AS TABLE 
(Name VARCHAR(Max)); 

另一种选择是使用XML Parameter

using (SqlConnection cnn = new SqlConnection("Your connection string")) 
{ 



    var sql = @"DECLARE @list AS TABLE (Name VARCHAR(20)) 
       INSERT INTO @list(Name) 
       SELECT t.name.value('.', 'varchar(MAX)') 
       FROM @Names.nodes('/Names/Name') as T(Name); 

       SELECT * 
       FROM INFORMATION_SCHEMA.ROUTINES 
       WHERE ROUTINE_TYPE in (SELECT Name from @list)"; 

    var sqlCmd = new SqlCommand(sql, cnn); 

    var s = new MemoryStream(ASCIIEncoding.Default.GetBytes("<Names><Name>PROCEDURE</Name><Name>FUNCTION</Name></Names>")); 


    var xmlParam = new SqlXml(s); 

    sqlCmd.Parameters.AddWithValue("@Names", xmlParam); 


    cnn.Open(); 
    using(SqlDataReader rdr = sqlCmd.ExecuteReader()) 
    { 
     while (rdr.Read()) 
      Console.WriteLine(rdr["SPECIFIC_NAME"]);      

    } 



} 
+0

我希望能够在不创建类型的情况下实现这一点,因为我的DBA正在抵制这种情况。 –

+1

不知道为什么你的DBA会抵制这一点。其影响相当低。我猜你其他的选择是XML。更新答案 –