Question

Cette page de SQL Server 2008 BOL , parle de CLR Stocké procédures et a une section intitulée « Paramètres de valeur table », qui parle de la façon dont ils peuvent être avantageux. C'est génial - j'aimerais utiliser TVPs dans mes procs CLR, mais malheureusement cela semble être la seule référence dans l'univers à une telle possibilité, et la section ne décrit pas ce que la syntaxe serait (pas plus que les autres informations liée à la fin du paragraphe)

Bien sûr, je peux facilement trouver des descriptions de l'utilisation TVPs de procs T-SQL, ou comment faire procs CLR en général. Mais l'écriture d'un proc CLR qui prend un PVT? Rien. Tout cela est très inhabituel depuis le passage des données multi-lignes à un proc stocké est un problème populaire.

Cela me conduit à se demander si la présence de la section sur cette page est une erreur. Quelqu'un s'il vous plaît dites-moi ce n'est pas et me pointer vers plus d 'info / exemples.

[EDIT]

J'étais sur le point de poster ce à l'un des forums MS aussi quand je suis tombé sur ce qui semble être le dernier clou dans le cercueil . On dirait qu'il ne peut se faire.

Était-ce utile?

La solution

Je peux trouver un plus références . Cependant, ce sont tous pour passer des paramètres table aux procédures TSQL, de sorte que l'utilisation est peu.

Cependant, je suis venu à la conclusion qu'il est impossible. Tout d'abord, il y a la des correspondances entre CLR et les types SQL. Pour les types de table il n'y a pas de correspondance, de sorte que la commande ne fonctionne pas, par exemple:

[SqlProcedure]
public static void StoredProcedure(DataTable tvp, out int sum)
{
    return 42;
}

et

CREATE TYPE MyTableType AS TABLE 
(
    Id INT NOT NULL PRIMARY KEY,
    [Count] INT NOT NULL
)
GO
CREATE ASSEMBLY ClrTest FROM '<somePath>'
GO
CREATE PROCEDURE ClrTest
AS EXTERNAL NAME ClrTest.StoredProcedures.StoredProcedure
GO

Quel que soit le type que vous essayez (DataTable, DbDataReader, IEnumerable), l'appel CREATE PROCEDURE garde générer une erreur 6552: CREATE PROCEDURE pour "CLRTest" a échoué parce que T-SQL et les types CLR pour le paramètre "@tvp" ne correspondent pas .

En second lieu, la documentation sur la page que vous avez lié à dit: Un type de table défini par l'utilisateur ne peut pas être passé en paramètre à valeur de table, ou être renvoyés de, une procédure stockée managée ou la fonction d'exécution dans le SQL processus serveur.

Je ne peux pas sembler trouver partout comment créer un type de table défini par l'utilisateur en C #, mais cela semble aussi être une impasse.

Peut-être que vous pouvez poser quelque part à votre question sur un forum Microsoft. Il est toujours étrange qu'ils mentionnent des paramètres table sur la page sproc CLR mais jamais expliquer comment mettre en œuvre. Si vous trouvez une solution, je voudrais savoir.

Autres conseils

Vous pouvez utiliser une table temporaire créée et peuplée avant d'appeler la procédure et de lire la table à l'intérieur de la procédure clr.

La solution consiste à sérialiser vos données tabulaires dans une chaîne au format JSON puis passer la chaîne dans votre proc CLR. Au sein de votre clr proc ou la fonction que vous souhaitez analyser le JSON à un IEnumerable, une liste ou objet tableau. Vous pouvez alors travailler avec les données que vous le feriez pour tout autre type de données tabulaires.

Je l'ai écrit quelques utilitaires capables de sérialisation une table SQL dans une chaîne au format JSON. Je serais heureux de les partager avec toute personne fournissant leur adresse e-mail. Factor Phil a écrit un bon analyseur JSON T-SQL qu'il a appelé parseJSON. Je l'ai adapté sa solution au clr qui effectue beaucoup plus rapide. Les deux acceptent une chaîne au format JSON et produire une table de la chaîne. J'ai aussi une variété d'utilitaires Json j'emploie à la fois avec T-SQL et CLR capable de sérialisation, l'analyse syntaxique, l'insertion, la suppression et la mise à jour des chaînes au format JSON stockées dans des colonnes SQL.

Si vous utilisez C # (par opposition à VB, qui manque itérateurs personnalisés) vous pouvez écrire du code ADO.NET pour appeler ExecuteNonQuery () et exécuter une procédure stockée avec un SqlDbType.Structured paramètre (par exemple, une TVP).

La collection passée en tant que valeur du PVT doit mettre en œuvre IEnumerable<SqlDataRecord>. Chaque fois que cette IEnumerable yield return est exécutée, SqlDataRecord « ligne » est reliée par pipeline au paramètre "table" .

Voir cet article pour plus de détails.

Bien qu'il ressemble à des tables passant directement aux procédures CLR est actuellement impossible, je suis arrivé un résultat, mais sous-optimal par:

  • définir une table TSQL valeur UDT FooTable
  • définir une fonction TSQL qui prend FooTable comme param et retourne XML en utilisant FOR XML EXPLICIT
  • passer le XML résultant à la fonction CLR / procédure au lieu de la table elle-même

Pas idéal, mais il devient un peu plus près.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top