J'ai une procédure stockée qui renvoie 80 colonnes et 300 lignes. Je veux écrire une sélection qui obtient 2 de ces colonnes. Quelque chose comme
SELECT col1, col2 FROM EXEC MyStoredProc 'param1', 'param2'
Lorsque j'ai utilisé la syntaxe ci-dessus, j'obtiens l'erreur:
"Nom de colonne invalide".
Je sais que la solution la plus simple serait de changer la procédure stockée, mais je ne l'ai pas écrite et je ne peux pas la changer.
Existe-t-il un moyen de faire ce que je veux?
Je pourrais faire une table temporaire pour y mettre les résultats, mais parce qu'il y a 80 colonnes, je devrais donc faire une table temporaire de 80 colonnes juste pour obtenir 2 colonnes. Je voulais éviter de retrouver toutes les colonnes retournées.
J'ai essayé d'utiliser
WITH SprocResults AS ....
comme suggéré par Mark, mais j'ai eu 2 erreursSyntaxe incorrecte près du mot clé "EXEC".
Syntaxe incorrecte près de ')'.J'ai essayé de déclarer une variable de table et j'ai eu l'erreur suivante
Erreur d'insertion: le nom de la colonne ou le nombre de valeurs fournies ne correspond pas à la définition de la table
Si j'essaye
SELECT * FROM EXEC MyStoredProc 'param1', 'param2'
j'obtiens l'erreur:Syntaxe incorrecte près du mot clé 'exec'.
la source
EXEC
n'est pas un mot clé MySQL (l'équivalent MySQL est des instructions préparées ). Bien que j'aimerais connaître la réponse pour MySQL, les réponses ci-dessous ciblent T-SQL. Redéfinir.Réponses:
Pouvez-vous diviser la requête? Insérez les résultats de proc stockés dans une variable de table ou une table temporaire. Ensuite, sélectionnez les 2 colonnes de la variable de table.
la source
Voici un lien vers un très bon document expliquant toutes les différentes façons de résoudre votre problème (bien que beaucoup d'entre elles ne puissent pas être utilisées car vous ne pouvez pas modifier la procédure stockée existante.)
Comment partager des données entre des procédures stockées
La réponse de Gulzar fonctionnera (elle est documentée dans le lien ci-dessus) mais ça va être compliqué à écrire (vous devrez spécifier les 80 noms de colonne dans votre instruction @tablevar (col1, ...). Et à l'avenir si une colonne est ajoutée au schéma ou si la sortie est modifiée, elle devra être mise à jour dans votre code ou elle entraînera une erreur.
la source
Source:
http://stevesmithblog.com/blog/select-from-a-stored-procedure/
la source
Cela fonctionne pour moi: (c'est-à-dire que je n'ai besoin que de 2 colonnes des 30+ retournées par
sp_help_job
)Avant que cela ne fonctionne, je devais exécuter ceci:
.... pour mettre à jour le
sys.servers
tableau. (Par exemple, l'utilisation d'une auto-référence dans OPENQUERY semble être désactivée par défaut.)Pour ma simple exigence, je n'ai rencontré aucun des problèmes décrits dans la section OPENQUERY de l'excellent lien de Lance.
Rossini, si vous avez besoin de définir dynamiquement ces paramètres d'entrée, alors l'utilisation de OPENQUERY devient un peu plus compliquée:
Je ne suis pas sûr des différences (le cas échéant) entre l'utilisation
sp_serveroption
pour mettre à joursys.servers
directement l'auto-référence existante et l'utilisationsp_addlinkedserver
(comme décrit dans le lien de Lance) pour créer un doublon / alias.Remarque 1: je préfère OPENQUERY à OPENROWSET, étant donné que OPENQUERY ne nécessite pas la définition de chaîne de connexion dans le proc.
Remarque 2: Cela dit: normalement, j'utiliserais simplement INSERT ... EXEC :) Oui, c'est 10 minutes de frappe supplémentaire, mais si je peux l'aider, je préfère ne pas bouger avec:
(a) les guillemets entre guillemets dans citations, et
(b) tables sys, et / ou configurations sournoises auto-référencées de serveur lié (c'est-à-dire pour celles-ci, je dois plaider ma cause auprès de nos DBA tout-puissants :)
Cependant, dans ce cas, je ne pouvais pas utiliser une construction INSERT ... EXEC, comme
sp_help_job
c'est déjà le cas. ("Une instruction INSERT EXEC ne peut pas être imbriquée.")la source
Pour ce faire, vous devez d'abord créer un
#test_table
comme ci-dessous:Maintenant, exécutez la procédure et mettez de la valeur dans
#test_table
:Maintenant, vous récupérez la valeur de
#test_table
:la source
Si vous pouvez modifier votre procédure stockée, vous pouvez facilement mettre les définitions de colonnes requises en tant que paramètre et utiliser une table temporaire créée automatiquement:
Dans ce cas, vous n'avez pas besoin de créer une table temporaire manuellement - elle est créée automatiquement. J'espère que cela t'aides.
la source
Il pourrait être utile de savoir pourquoi cela est si difficile. Une procédure stockée peut uniquement renvoyer du texte («texte» imprimé), ou renvoyer plusieurs tableaux, ou ne renvoyer aucun tableau du tout.
Donc, quelque chose comme ça
SELECT * FROM (exec sp_tables) Table1
ne fonctionnera pasla source
(En supposant que SQL Server)
La seule façon de travailler avec les résultats d'une procédure stockée dans T-SQL est d'utiliser la
INSERT INTO ... EXEC
syntaxe. Cela vous donne la possibilité d'insérer dans une table temporaire ou une variable de table et de sélectionner les données dont vous avez besoin.la source
Un hack rapide serait d'ajouter un nouveau paramètre
'@Column_Name'
et de faire définir par la fonction appelante le nom de la colonne à récupérer. Dans la partie de retour de votre sproc, vous auriez des instructions if / else et ne renverriez que la colonne spécifiée, ou si vide - renvoyez tout.la source
Si vous faites cela pour une validation manuelle des données, vous pouvez le faire avec LINQPad.
Créez une connexion à la base de données dans LinqPad, puis créez des instructions C # similaires aux suivantes:
Référence http://www.global-webnet.net/blogengine/post/2008/09/10/LINQPAD-Using-Stored-Procedures-Accessing-a-DataSet.aspx
la source
Pour SQL Server, je trouve que cela fonctionne bien:
Créez une table temporaire (ou une table permanente, cela n'a pas vraiment d'importance) et effectuez une insertion dans l'instruction par rapport à la procédure stockée. Le jeu de résultats du SP doit correspondre aux colonnes de votre table, sinon vous obtiendrez une erreur.
Voici un exemple:
C'est ça!
la source
Comme cela a été mentionné dans la question, il est difficile de définir la table temporaire de 80 colonnes avant d'exécuter la procédure stockée.
Donc, l'inverse consiste à remplir la table en fonction de l'ensemble de résultats de la procédure stockée.
Si vous obtenez une erreur, vous devez activer les requêtes distribuées ad hoc en exécutant la requête suivante.
Pour exécuter
sp_configure
avec les deux paramètres afin de modifier une option de configuration ou d'exécuter l'RECONFIGURE
instruction, vous devez disposer de l'ALTER SETTINGS
autorisation au niveau du serveurVous pouvez maintenant sélectionner vos colonnes spécifiques dans le tableau généré
la source
essaye ça
la source
Je sais que l'exécution depuis sp et l'insertion dans une table temporaire ou une variable de table serait une option, mais je ne pense pas que ce soit votre exigence. Selon vos besoins, cette déclaration de requête ci-dessous devrait fonctionner:
si vous avez une connexion de confiance, utilisez cette instruction de requête ci-dessous:
si vous obtenez une erreur lors de l'exécution de l'instruction ci-dessus, exécutez simplement cette instruction ci-dessous:
J'espère que cela aidera quelqu'un qui aura fait face à ce genre de problème similaire. Si quelqu'un veut essayer avec une table temporaire ou une variable de table qui devrait ressembler à ceci ci-dessous, mais dans ce scénario, vous devez savoir combien de colonnes votre sp renvoie, alors vous devez créer autant de colonnes dans la table temporaire ou la variable de table:
la source
Pour tous ceux qui ont SQL 2012 ou version ultérieure, j'ai pu accomplir cela avec des procédures stockées qui ne sont pas dynamiques et ont les mêmes colonnes de sortie à chaque fois.
L'idée générale est que je construis la requête dynamique pour créer, insérer, sélectionner et supprimer la table temporaire, et l'exécuter une fois qu'elle est entièrement générée. Je génère dynamiquement la table temporaire en récupérant d' abord les noms et types de colonnes de la procédure stockée .
Remarque: il existe des solutions bien meilleures et plus universelles qui fonctionneront avec moins de lignes de code si vous souhaitez / pouvez mettre à jour le SP ou modifier la configuration et l'utilisation
OPENROWSET
. Utilisez ce qui suit si vous n'avez pas d'autre moyen.la source
Le moyen le plus simple de le faire si vous n'en avez besoin qu'une fois:
Exportez vers Excel dans l'assistant d'importation et d'exportation, puis importez cet Excel dans une table.
la source
Créez une vue dynamique et obtenez-en des résultats .......
la source
Je voudrais couper et coller le SP d'origine et supprimer toutes les colonnes sauf les 2 que vous voulez. Ou. Je ramènerais l'ensemble de résultats, le mapperais à un objet métier approprié, puis LINQ sur les deux colonnes.
la source