web-dev-qa-db-fra.com

Récupérer par programme la source de procédure stockée SQL Server qui est identique à la source retournée par l'interface graphique de SQL Server Management Studio?

Des pointeurs sur la façon dont je peux obtenir par programme exactement la source de procédure stockée identique à partir de SQL Server 2005, comme lorsque je clique avec le bouton droit sur cette procédure stockée dans SQL Server Management Studio et sélectionne modifier?

J'essaie d'utiliser SMO, mais il existe des différences textuelles. La procédure a toujours CREATE, pas ALTER, et il y a quelques différences dans l'en-tête, comme des GO manquants dans la version que je reçois par programme. Je peux les réparer, mais peut-être y a-t-il une meilleure façon?

Encore une fois, je suis dans SQL Server 2005, en utilisant SMSE. Utilisation de SMO via Visual Studio 8 2008.

Mise à jour: Obtenu des réponses qui expliquent les bases de la récupération de la procédure stockée. Ce que je recherche, c'est récupérer le texte identique (ou presque identique) à ce que génère l'interface graphique.

Exemple: pour sp_mysp, cliquez avec le bouton droit dans Management Studio, sélectionnez modifier. Cela génère:

    USE [MY_DB] 
 GO 
/****** Object: StoredProcedure [dbo]. [Sp_mysp] Date du script: 21/01/2009 17:43:18 ***** */
 METTRE ANSI_NULLS SUR 
 ALLER 
 METTRE QUOTED_IDENTIFIER SUR 
 ALLER 
 - ============== ================================ 
 - Auteur: 
 - Créer une date : 
 - Description: 
 - ================================== ============ 
 ALTER PROCEDURE [dbo]. [Sp_mysp] 

Je voudrais obtenir par programme la même chose (notez les GO dans l'en-tête et le fait qu'il s'agit d'une ALTER PROCEDURE. Idéalement, j'aimerais obtenir cela avec une correction programmatique minimale de la source récupérée.

Je serais heureux de n'obtenir que quelque chose qui différait dans les détails de la date du script. . .

64
DWright
EXEC sp_helptext 'your procedure name';

Cela évite le problème avec l'approche INFORMATION_SCHEMA dans laquelle la procédure stockée est coupée si elle est trop longue.

Mise à jour: David écrit que ce n'est pas identique à son sproc ... peut-être parce qu'il retourne les lignes comme des "enregistrements" pour conserver la mise en forme? Si vous voulez voir les résultats dans un format plus "naturel", vous pouvez d'abord utiliser Ctrl-T (sortie sous forme de texte) et il devrait l'imprimer exactement comme vous l'avez entré. Si vous faites cela dans du code, il est trivial de faire un foreach pour rassembler vos résultats exactement de la même manière.

Mise à jour 2: Cela fournira à la source une "PROCÉDURE DE CRÉATION" plutôt qu'une "PROCÉDURE DE MODIFICATION" mais je ne connais aucun moyen de lui faire utiliser "ALTER" à la place. Une sorte de chose triviale, cependant, n'est-ce pas?

Mise à jour 3: Voir les commentaires pour plus d'informations sur la façon de maintenir votre SQL DDL (structure de base de données) dans un système de contrôle de source. C'est vraiment la clé de cette question.

81
Mark Brittingham

Vous devrez le coder manuellement, SQL Profiler révèle ce qui suit.

SMSE exécute une longue chaîne de requêtes lorsqu'il génère l'instruction.

La requête suivante (ou quelque chose dans son sens) est utilisée pour extraire le texte:

SELECT
NULL AS [Text],
ISNULL(smsp.definition, ssmsp.definition) AS [Definition]
FROM
sys.all_objects AS sp
LEFT OUTER JOIN sys.sql_modules AS smsp ON smsp.object_id = sp.object_id
LEFT OUTER JOIN sys.system_sql_modules AS ssmsp ON ssmsp.object_id = sp.object_id
WHERE
(sp.type = N'P' OR sp.type = N'RF' OR sp.type='PC')and(sp.name=N'#test___________________________________________________________________________________________________________________00003EE1' and SCHEMA_NAME(sp.schema_id)=N'dbo')

Il retourne le CREATE pur qui est ensuite remplacé par ALTER dans le code quelque part.

Les éléments SET ANSI NULL et les instructions et dates GO sont tous ajoutés avant cela.

Allez avec sp_helptext, c'est plus simple ...

15
Sam Saffron

Vous avez dit par programme, non? J'espère que C # est ok. Je sais que vous avez dit que vous avez essayé SMO et qu'il n'a pas tout à fait fait ce que vous vouliez, donc cela ne sera probablement pas parfait pour votre demande, mais il lira par programme des instructions SQL légitimes que vous pourriez exécuter pour recréer la procédure stockée. S'il ne contient pas les instructions GO que vous souhaitez, vous pouvez probablement supposer que chacune des chaînes dans le StringCollection pourrait avoir un GO après. Vous ne pouvez pas obtenir ce commentaire avec la date et l'heure, mais dans mon projet de sondage similaire (outil de déploiement big-ass qui doit tout sauvegarder individuellement), cela s'est plutôt bien passé. Si vous avez une base antérieure à partir de laquelle vous vouliez travailler et que vous avez toujours la base de données d'origine pour exécuter cela, j'envisagerais de jeter l'effort initial et de normaliser cette sortie.

using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
…
string connectionString = … /* some connection string */;
ServerConnection sc = new ServerConnection(connectionString);
Server s = new Server(connection);
Database db = new Database(s, … /* database name */);
StoredProcedure sp = new StoredProcedure(db, … /* stored procedure name */);
StringCollection statements = sp.Script;
11
Hunter

Utilisez l'instruction select suivante pour obtenir toute la définition:

select ROUTINE_DEFINITION from INFORMATION_SCHEMA.ROUTINES Where ROUTINE_NAME='someprocname'

je suppose que SSMS et d'autres outils lisent ceci et apportent des modifications si nécessaire, comme changer CREATE en ALTER. Pour autant que je sache, SQL ne stocke pas d'autres représentations de la procédure

7
keithwarren7

Je suis d'accord avec Mark. J'ai mis la sortie en mode texte, puis sp_HelpText 'sproc'. Je l'ai lié à Crtl-F1 pour le rendre facile.

5
BankZ

Assistant de publication de base de données peut vider le schéma (et d'autres objets) à partir de la ligne de commande.

4
Chris Nava

Je veux juste noter qu'au lieu d'utiliser rechercher et remplacer pour modifier la procédure de création pour modifier la procédure, vous pouvez tout aussi bien utiliser une goutte, vous pouvez la placer tout en haut et cela nécessite une recherche de texte.

IF exists (SELECT * FROM sys.objects 
        WHERE object_id = OBJECT_ID(N'sp_name')
            and type in ('P','V') --procedure or view
        )
    DROP sp_name
GO

Si vous êtes sûr qu'il est là, je suppose que vous pouvez aussi le laisser tomber, mais je ne le recommanderais pas. N'oubliez pas, car la procédure de création doit être la première et la seule instruction d'un lot.

Ou l'approche paresseuse:

IF OBJECT_ID(N'sp_name') is not null
    DROP sp_name
GO
2
Kevin