C # Aufruf der benutzerdefinierten Skalar-function in SQL server, die den Tabellen-Typ als Parameter enthält

Ich habe meinen Kopf gegen einen Rock geschlagen. Ich habe eine Skalar-function geschrieben, die einen Tabellen-Typ, den ich als Parameter erstellt habe, und es gibt einen einfachen Varchar hier ist der SQL-Code, wenn es hilft

ALTER FUNCTION [dbo].[pe_Get_Manufacturer] ( -- Add the parameters for the function here @Row [dbo].[pe_StringList] READONLY ) RETURNS VARCHAR(103) AS BEGIN DECLARE @OUT VARCHAR(50) DECLARE @tempTable TABLE ( Position INT, ManuName CHAR(100), ManuCat CHAR(3) ) INSERT INTO @tempTable SELECT DISTINCT r.Position, c.ima_mfg, c.ima_cat FROM dbo.[Admin_ MFR Aliases] as c INNER JOIN @Row r ON c.orig_mfg = r.Candidate OR c.ima_mfg = r.Candidate OR c.orgmfgstrp = r.Candidate ORDER BY r.Position SELECT TOP 1 @OUT = LTRIM(RTRIM(ManuName)) + '^' + COALESCE(ManuCat,'') FROM @tempTable ORDER BY Position DESC -- Return the result of the function RETURN @OUT END 

auf meiner C # -Seite habe ich ein Funcation, das nimmt, ist eine list von Strings, die in ein Datatable gesetzt werden soll, um als Parameter für die function verwendet zu werden. Ich glaube ich habe geschrieben, das ist alles richtig, wie auch immer mein Projekt wirft, wenn es darum geht, ExecuteScalar auf dem SQLCommand auszuführen

 public string getManufacturer(IList<string> list) { int counter = 1; DataTable dataTable = new DataTable(); dataTable.Columns.Add("Position", typeof (int)); dataTable.Columns.Add("Candidate", typeof (string)); foreach (var candidate in list) { DataRow dataRow = dataTable.NewRow(); dataRow["Position"] = counter++; dataRow["Candidate"] = candidate; dataTable.Rows.Add(dataRow); } SqlParameter tableType = new SqlParameter("@Row" , SqlDbType.Structured) { TypeName = "dbo.pe_StringList", Value = dataTable }; string query = " SELECT * FROM dbo.pe_Get_Manufacturer(@Row)"; SqlCommand sqlCommand = new SqlCommand(query, conn); sqlCommand.Parameters.AddWithValue("@Row", tableType); return sqlCommand.ExecuteScalar().ToString(); } 

Dies ist die Information, die ich aus der exception bekomme:

"Eine exception des Typs" System.ArgumentException "ist in System.Data.dll aufgetreten, wurde aber nicht im Benutzercode behandelt

Zusätzliche Informationen: Es existiert keine Zuordnung vom objecttyp System.Data.SqlClient.SqlParameter zu einem bekannten Managed Provider nativen Typ. "

EDIT —- das ist die Tabelle Typ, die ich erstellt habe

 CREATE TYPE pe_StringList AS TABLE ( Position INT, Candidate VARCHAR(50) ) 

Ich habe die Abfrage geändert

 string query = " SELECT * FROM dbo.pe_Get_Manufacturer(@Row)"; 

Nach

 string query = " SELECT dbo.pe_Get_Manufacturer(@Row)"; 

Einfach ändern:

 sqlCommand.Parameters.AddWithValue("@Row", tableType); 

sein:

 sqlCommand.Parameters.Add(tableType); 

da es sich schon um einen SqlParameter Typ handelt. Du würdest AddWithValue , um den SqlParameter on-the-fly zu erstellen (bitte sehe meine Anmerkung unten, um diese veraltete Methode nicht zu verwenden), aber du hast bereits den SqlParameter und musst ihn nur der Sammlung hinzufügen.

Und ja, das Entfernen von * FROM aus der Abfrage war auch aus einem rein T-SQL-Syntax-Standpunkt notwendig.


Side Note: Es ist am besten, nicht AddWithValue auf jeden Fall, immer ;-):

  • Unterschied zwischen Parametern.Add und Parameters.AddWithValue
  • Können wir mit AddWithValue () schon aufhören?

Versuche es zu ändern

 sqlCommand.Parameters.AddWithValue("@Row", tableType); 

nach

 sqlCommand.Parameters.AddWithValue("@Row", dataTable); 

Sie legen den Wert des Parameters fest, den Sie mit einem Wert zu einem SqlParameter hinzufügen, der nicht benötigt wird.

SqlParameterCollection.AddWithValue Methode