sql-server - variable - show procedure sql server




Sélectionner les colonnes du jeu de résultats de la procédure stockée (11)

J'ai une procédure stockée qui renvoie 80 colonnes et 300 lignes. Je veux écrire un select qui obtient 2 de ces colonnes. Quelque chose comme

SELECT col1, col2 FROM EXEC MyStoredProc 'param1', 'param2'

Quand j'ai utilisé la syntaxe ci-dessus, j'ai 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.

Y a-t-il un moyen de faire ce que je veux?

  • Je pourrais faire une table temporaire pour mettre les résultats dedans, mais parce qu'il y a 80 colonnes ainsi je devrais faire une table de la température 80 de colonne juste pour obtenir 2 colonnes. Je voulais éviter de retrouver toutes les colonnes qui sont retournées.

  • J'ai essayé d'utiliser WITH SprocResults AS .... comme suggéré par Mark, mais j'ai eu 2 erreurs

    Syntaxe 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'ai l'erreur:

    Syntaxe incorrecte près du mot-clé 'exec'.


(En supposant 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 syntaxe INSERT INTO ... EXEC . Cela vous donne la possibilité de l'insérer dans une table temporaire ou une variable de table et de sélectionner les données dont vous avez besoin.


Avez-vous essayé ceci:

  • créer une fonction qui devrait appeler ce StoredProcedure
  • utiliser un curseur pour stocker les résultats renvoyés par StoredProcedure
  • boucle ce curseur, afin que vous puissiez imprimer / stocker ces deux colonnes dont vous avez besoin dans la table temporaire (avec 2columns seulement)
  • puis utilisez cette table pour sélectionner les résultats

Comme cela a été mentionné dans la question, il est difficile de définir la table temporaire 80 colonnes avant d'exécuter la procédure stockée.

Donc, l'inverse consiste à remplir la table en fonction du jeu de résultats de la procédure stockée.

SELECT * INTO #temp FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;'
                                   ,'EXEC MyStoredProc')

Si vous rencontrez une erreur, vous devez activer les requêtes distribuées ad hoc en exécutant la requête suivante.

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

Pour exécuter sp_configure avec les deux paramètres afin de modifier une option de configuration ou pour exécuter l'instruction RECONFIGURE , vous devez disposer de l'autorisation ALTER SETTINGS niveau du serveur ALTER SETTINGS

Vous pouvez maintenant sélectionner vos colonnes spécifiques dans la table générée

SELECT col1, col2
FROM #temp

Il pourrait être utile de savoir pourquoi c'est si difficile. Une procédure stockée peut renvoyer uniquement du texte (print 'text') ou renvoyer plusieurs tables, ou peut ne renvoyer aucune table.

Donc, quelque chose comme SELECT * FROM (exec sp_tables) Table1 ne fonctionnera pas


Le moyen le plus simple de le faire si vous en avez seulement besoin une fois:

Exporter vers Excel dans l'Assistant Importation et exportation, puis importer cette Excel dans une table.


Pour SQL Server, je trouve que cela fonctionne bien:

Créer une table temporaire (ou une table permanente, n'a pas vraiment d'importance), et faire une insertion dans l'instruction contre la procédure stockée. L'ensemble de résultats du SP doit correspondre aux colonnes de votre tableau, sinon vous obtiendrez une erreur.

Voici un exemple:

DECLARE @temp TABLE (firstname NVARCHAR(30), lastname nvarchar(50));

INSERT INTO @temp EXEC dbo.GetPersonName @param1,@param2;
-- assumption is that dbo.GetPersonName returns a table with firstname / lastname columns

SELECT * FROM @temp;

C'est tout!


Pouvez-vous séparer la requête? Insérez les résultats du proc stocké dans une variable de table ou une table temporaire. Ensuite, sélectionnez les 2 colonnes de la variable de table.

Declare @tablevar table(col1 col1Type,..
insert into @tablevar(col1,..) exec MyStoredProc 'param1', 'param2'

SELECT col1, col2 FROM @tablevar

Si vous êtes en mesure de modifier votre procédure stockée, vous pouvez facilement placer les définitions de colonnes requises en tant que paramètre et utiliser une table temporaire créée automatiquement:

CREATE PROCEDURE sp_GetDiffDataExample
      @columnsStatement NVARCHAR(MAX) -- required columns statement (e.g. "field1, field2")
AS
BEGIN
    DECLARE @query NVARCHAR(MAX)
    SET @query = N'SELECT ' + @columnsStatement + N' INTO ##TempTable FROM dbo.TestTable'
    EXEC sp_executeSql @query
    SELECT * FROM ##TempTable
    DROP TABLE ##TempTable
END

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.


Un hack rapide serait d'ajouter un nouveau paramètre '@Column_Name' et de faire en sorte que la fonction appelante définisse le nom de la colonne à extraire. Dans la partie return de votre sproc, vous devriez avoir des instructions if / else et ne renvoyer que la colonne spécifiée, ou si elle est vide, renvoyer tout.

CREATE PROCEDURE [dbo].[MySproc]
        @Column_Name AS VARCHAR(50)
AS
BEGIN
    IF (@Column_Name = 'ColumnName1')
        BEGIN
            SELECT @ColumnItem1 as 'ColumnName1'
        END
    ELSE
        BEGIN
            SELECT @ColumnItem1 as 'ColumnName1', @ColumnItem2 as 'ColumnName2', @ColumnItem3 as 'ColumnName3'
        END
END

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 eux ne peuvent pas être utilisés puisque 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 cela va être compliqué à écrire (vous devrez spécifier les 80 noms de colonnes dans votre instruction @tablevar (col1, ...). Si une colonne est ajoutée au schéma ou que la sortie est modifiée, elle devra être mise à jour dans votre code ou elle sera erronée.








stored-procedures