2011-08-08 7 views
29

मैं संग्रहीत प्रक्रिया में तालिका-मान पैरामीटर पास करने का प्रयास कर रहा हूं, लेकिन मुझे अपवाद मिल रहा है (नीचे देखें)। IQueryable<int>तालिका-मान पैरामीटर को कैसे पास करें

CREATE TYPE [dbo].[IdList] AS TABLE(
    [Id] [int] NOT NULL 
)

मैं एक List<int> रूप sharedPdfs गुजर की कोशिश की है, और है, लेकिन हो रही निम्न अपवाद रखें::

SqlCommand c = new SqlCommand("getPermittedUsers", myConn) { CommandType = CommandType.StoredProcedure }; 

c.Parameters.AddWithValue("@intNotifyingUserId", notifyingUserId); 
c.Parameters.AddWithValue("@tSelectedPdfIds", sharedPdfs).SqlDbType = SqlDbType.Structured; 

SqlDataReader dr = c.ExecuteReader();

प्रकार इस तरह सर्वर पर परिभाषित किया गया है

Object must implement IConvertible.

कोई भी जानता है कि मैं क्या गलत कर रहा हूं? दस्तावेज़ीकरण का तात्पर्य है कि मुझे एक टीवीपी के रूप में एक सूची पास करने में सक्षम होना चाहिए लेकिन कोई उदाहरण नहीं देता है।

धन्यवाद।

+0

कैसे 'getPermittedUsers' घोषित किया जाता है? –

+0

यह एक लंबा शॉट है, लेकिन क्या आपने 'int [] 'पास करने का प्रयास किया है? –

+4

आपको 'डेटाटेबल' का उपयोग करने की आवश्यकता है। – ChaosPandion

उत्तर

12

आप पैरामीटर को DataTable, IEnumerable<SqlDataRecord>, या DbDataReader के रूप में पास कर सकते हैं।

+0

? एसक्यूएलकॉमैंड के लिए क्या आप निश्चित हैं? –

+1

हां, वे SQLCommand में तालिका-मान पैरामीटर के लिए समर्थित प्रकार हैं। पूर्ण दस्तावेज यहां है: http://msdn.microsoft.com/en-us/library/bb675163.aspx। नीचे से 1/3 नीचे देखें: "System.Data.SqlClient डेटाटेबल, डीबीडेटा रीडर या सिस्टम से पॉप्युलेटिंग टेबल-मूल्यवान पैरामीटर का समर्थन करता है। चयन। जेनेरिक। INumerable ([टी: System.Collections.Generic.IEnumerable' 1)] वस्तुओं। " –

+1

क्या यह ओरेकल में भी संभव है? –

42

निम्न उदाहरण का उपयोग कर दिखाता है या तो एक DataTable या एक IEnumerable<SqlDataRecord>:

एसक्यूएल कोड

CREATE TABLE dbo.PageView 
(
    PageViewID BIGINT NOT NULL CONSTRAINT pkPageView PRIMARY KEY CLUSTERED, 
    PageViewCount BIGINT NOT NULL 
); 
CREATE TYPE dbo.PageViewTableType AS TABLE 
(
    PageViewID BIGINT NOT NULL 
); 
CREATE PROCEDURE dbo.procMergePageView 
    @Display dbo.PageViewTableType READONLY 
AS 
BEGIN 
    MERGE INTO dbo.PageView AS T 
    USING @Display AS S 
    ON T.PageViewID = S.PageViewID 
    WHEN MATCHED THEN UPDATE SET T.PageViewCount = T.PageViewCount + 1 
    WHEN NOT MATCHED THEN INSERT VALUES(S.PageViewID, 1); 
END 

सी # कोड

private static void ExecuteProcedure(bool useDataTable, string connectionString, IEnumerable<long> ids) { 
    using (SqlConnection connection = new SqlConnection(connectionString)) { 
     connection.Open(); 
     using (SqlCommand command = connection.CreateCommand()) { 
      command.CommandText = "dbo.procMergePageView"; 
      command.CommandType = CommandType.StoredProcedure; 

      SqlParameter parameter; 
      if (useDataTable) { 
       parameter = command.Parameters.AddWithValue("@Display", CreateDataTable(ids)); 
      } 
      else { 
       parameter = command.Parameters.AddWithValue("@Display", CreateSqlDataRecords(ids)); 
      } 
      parameter.SqlDbType = SqlDbType.Structured; 
      parameter.TypeName = "dbo.PageViewTableType"; 

      command.ExecuteNonQuery(); 
     } 
    } 
} 

private static DataTable CreateDataTable(IEnumerable<long> ids) { 
    DataTable table = new DataTable(); 
    table.Columns.Add("ID", typeof(long)); 
    foreach (long id in ids) { 
     table.Rows.Add(id); 
    } 
    return table; 
} 

private static IEnumerable<SqlDataRecord> CreateSqlDataRecords(IEnumerable<long> ids) { 
    SqlMetaData[] metaData = new SqlMetaData[1]; 
    metaData[0] = new SqlMetaData("ID", SqlDbType.BigInt); 
    SqlDataRecord record = new SqlDataRecord(metaData); 
    foreach (long id in ids) { 
     record.SetInt64(0, id); 
     yield return record; 
    } 
} 
+1

इससे मेरी मदद की, धन्यवाद! – s0nica

+0

मुझे http://sqlperformance.com/2012/08/t-sql-queries/splitting-strings-now-with-less-t-sql पर मिले टीवी से काम करने का प्रयास कर रहा था, लेकिन dbnull मान प्राप्त करना जारी रखा। आपका उदाहरण मेरे लिए काम करना समाप्त हो गया है, पैरामीटर हो सकता है .typename। धन्यवाद! – Phil

+0

एनबी: उन लोगों के लिए जो इस के लिए एक कस्टम प्रकार नहीं बनाना चाहते हैं, एक वर्कअराउंड डेटा को एक्सएमएल प्रकार के रूप में पास करना है, फिर उसके खिलाफ पूछताछ करें। – JohnLBevan

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^