2016-01-26 1 views
4

Je me suis cogné la tête contre un problème. J'ai écrit une fonction scalaire qui prend un type de table que j'ai créé en tant que paramètre et retourne simple varchar est le code sql ici si elle aide de mon côté C#C# appelant la fonction User Defined Scalar dans SQL Server qui prend le type de table comme paramètre

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 

J'ai un funcation qui prend une liste des chaînes qui doivent être mises dans un Datatable à utiliser comme paramètre pour la fonction. Je crois que je l'ai écrit tout cela est correctement comment jamais mon projet jette quand il va courir ExecuteScalar sur le SQLCommand

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(); 

    } 

Ce sont les informations que je reçois de l'exception:

« Une exception de type ' System.ArgumentException » a eu lieu en System.Data.dll mais n'a pas été traitée dans le code utilisateur

informations complémentaires: Aucun mappage existe à partir du type d'objet System.Data.SqlClient.SqlParameter à un fournisseur managé connu natif de type . "

EDIT ---- c'est le type de table que j'ai créé

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

J'ai changé la requête de

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

Pour

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

Quelle est la définition du type pe_StringList ? Et est-ce que 'SELECT * FROM dbo.pe_Get_Manufacturer (@Row)' fonctionne s'il est appelé avec SSMS? – MattC

+0

Qu'est-ce que '[dbo]. [Pe_StringList]'? –

+0

qui est le type de table que j'ai fait – Fresh

Répondre

4

changer simplement:

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

être:

sqlCommand.Parameters.Add(tableType); 

car il est déjà un type SqlParameter. Vous utiliseriez AddWithValue pour créer le SqlParameter à la volée (bien que s'il vous plaît voir ma note au bas de ne pas utiliser cette méthode obsolète), mais vous avez déjà créé le SqlParameter et juste besoin de l'ajouter à la collection.

Et oui, supprimer le * FROM de la requête était également nécessaire d'un point de vue de la syntaxe purement T-SQL.


Side note: il est préférable de ne pas utiliser AddWithValue dans tous les cas, jamais ;-):

+0

Serait utile si vous avez expliqué ce commentaire: 'Side note: il est préférable de ne pas utiliser AddWithValue dans tous les cas, jamais ;-).' –

+0

@MetroSmurf Espérait être paresseux et ne pas rechercher la référence :-p. Mais bon appel, j'ai donc ajouté deux liens. –

+1

Hey ça a marché. Merci beaucoup! C'est réconfortant de savoir que je n'étais pas loin. – Fresh

0

Essayez de changer

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

à

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

vous réglez la valeur du paramètre que vous ajoutez une valeur à un SqlParameter qui n'est pas nécessaire.

SqlParameterCollection.AddWithValue Method

+0

J'ai essayé ce que vous avez suggéré encore throws mais le message d'exception est remplacé par "Informations supplémentaires: Le paramètre de type de table" @Row "doit avoir un nom de type valide." – Fresh