web-dev-qa-db-fra.com

Comment trouver un texte dans les procédures/déclencheurs de SQL Server?

J'ai un serveur lié qui va changer. Certaines procédures appellent le serveur lié comme suit: [10.10.100.50].dbo.SPROCEDURE_EXAMPLE. Nous avons aussi des déclencheurs qui font ce genre de travail. Nous devons trouver tous les endroits qui utilisent [10.10.100.50] pour le changer.

Dans SQL Server Management Studio Express, je n'ai pas trouvé de fonctionnalité telle que "trouver dans la base de données entière" dans Visual Studio. Un système spécial -sys select peut-il m'aider à trouver ce dont j'ai besoin?

162
Victor Rodrigues

voici une partie d’une procédure que j’utilise sur mon système pour rechercher du texte ....

DECLARE @Search varchar(255)
SET @Search='[10.10.100.50]'

SELECT DISTINCT
    o.name AS Object_Name,o.type_desc
    FROM sys.sql_modules        m 
        INNER JOIN sys.objects  o ON m.object_id=o.object_id
    WHERE m.definition Like '%'+@Search+'%'
    ORDER BY 2,1
278
KM.

[Réponse tardive, mais j'espère utile]

L'utilisation de tables système ne donne pas toujours des résultats corrects à 100%, car il est possible que certaines procédures stockées et/ou vues soient chiffrées. Dans ce cas, vous devrez utiliser DAC connection pour obtenir les données que vous avez saisies. avoir besoin.

Je vous recommande d'utiliser un outil tiers, tel que ApexSQL Search , qui peut traiter facilement les objets chiffrés. 

La table système Syscomments donnera une valeur nulle pour la colonne de texte si l'objet est chiffré. 

17
Dwoolk

Vous pouvez le trouver comme 

SELECT DISTINCT OBJECT_NAME(id) FROM syscomments WHERE [text] LIKE '%User%'

Il répertoriera les noms de procédure stockée distincts contenant du texte tel que "Utilisateur" dans la procédure stockée. Plus d'informations

16
ashish.chotalia
-- Declare the text we want to search for
DECLARE @Text nvarchar(4000);
SET @Text = 'employee';

-- Get the schema name, table name, and table type for:

-- Table names
SELECT
       TABLE_SCHEMA  AS 'Object Schema'
      ,TABLE_NAME    AS 'Object Name'
      ,TABLE_TYPE    AS 'Object Type'
      ,'Table Name'  AS 'TEXT Location'
FROM  INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%'+@Text+'%'
UNION
 --Column names
SELECT
      TABLE_SCHEMA   AS 'Object Schema'
      ,COLUMN_NAME   AS 'Object Name'
      ,'COLUMN'      AS 'Object Type'
      ,'Column Name' AS 'TEXT Location'
FROM  INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%'+@Text+'%'
UNION
-- Function or procedure bodies
SELECT
      SPECIFIC_SCHEMA     AS 'Object Schema'
      ,ROUTINE_NAME       AS 'Object Name'
      ,ROUTINE_TYPE       AS 'Object Type'
      ,ROUTINE_DEFINITION AS 'TEXT Location'
FROM  INFORMATION_SCHEMA.ROUTINES 
WHERE ROUTINE_DEFINITION LIKE '%'+@Text+'%'
      AND (ROUTINE_TYPE = 'function' OR ROUTINE_TYPE = 'procedure');
11
Heba Mahmoud

Cela fonctionnera pour vous:

use [ANALYTICS]  ---> put your DB name here
GO
SELECT sm.object_id, OBJECT_NAME(sm.object_id) AS object_name, o.type, o.type_desc, sm.definition
FROM sys.sql_modules AS sm
JOIN sys.objects AS o ON sm.object_id = o.object_id
where sm.definition like '%SEARCH_Word_HERE%' collate SQL_Latin1_General_CP1_CI_AS
ORDER BY o.type;
GO
5
laurens

Il existe beaucoup de meilleures solutions que de modifier le texte de vos procédures, fonctions et vues stockées chaque fois que le serveur lié change. Voici quelques options:

  1. Mettez à jour le serveur lié. Au lieu d'utiliser un serveur lié nommé avec son adresse IP, créez un nouveau serveur lié avec le nom de la ressource tel que Finance ou DataLinkProd ou quelque chose de ce genre. Ensuite, lorsque vous devez changer de serveur, mettez à jour le serveur lié pour qu'il pointe vers le nouveau serveur (ou supprimez-le et recréez-le).

  2. Bien que, malheureusement, vous ne puissiez pas créer de synonymes pour des serveurs ou des schémas liés, vous pouvez créer des synonymes pour des objets situés sur des serveurs liés. Par exemple, votre procédure [10.10.100.50].dbo.SPROCEDURE_EXAMPLE pourrait être aliasée. Peut-être créer un schéma datalinkprod, puis CREATE SYNONYM datalinkprod.dbo_SPROCEDURE_EXAMPLE FOR [10.10.100.50].dbo.SPROCEDURE_EXAMPLE;. Ensuite, écrivez une procédure stockée qui accepte un nom de serveur lié, qui interroge tous les objets potentiels de la base de données distante et crée (ou crée) des synonymes pour ceux-ci. Tous vos SP et fonctions sont réécrits une seule fois pour utiliser les noms de synonymes commençant par datalinkprod, et après cela, pour passer d'un serveur lié à un autre, vous ne faites que EXEC dbo.SwitchLinkedServer '[10.10.100.51]'; et en une fraction de seconde, vous utilisez un autre serveur lié .

Il peut y avoir encore plus d'options. Je recommande fortement d'utiliser les techniques supérieures de pré-traitement, de configuration ou d'indirection plutôt que de changer les scripts écrits par l'homme. Mettre à jour automatiquement les scripts créés par la machine, c'est bien, il s'agit d'un prétraitement. Faire les choses manuellement est affreux.

4
ErikE
select text
from syscomments
where text like '%your text here%'
2
Rez.Net

Je viens d'écrire ceci pour une référence générique externe complète

create table #XRefDBs(xtype varchar(2),SourceDB varchar(100), Object varchar(100), RefDB varchar(100))

declare @sourcedbname varchar(100),
        @searchfordbname varchar(100),
        @sql nvarchar(4000)
declare curs cursor for
    select name 
    from sysdatabases
    where dbid>4
open curs
fetch next from curs into @sourcedbname
while @@fetch_status=0
    begin
    print @sourcedbname
    declare curs2 cursor for 
        select name 
        from sysdatabases
        where dbid>4
        and name <> @sourcedbname
    open curs2
    fetch next from curs2 into @searchfordbname
    while @@fetch_status=0
        begin
        print @searchfordbname
        set @sql = 
        'INSERT INTO #XRefDBs (xtype,SourceDB,Object, RefDB)
        select DISTINCT o.xtype,'''+@sourcedbname+''', o.name,'''+@searchfordbname+'''
        from '+@sourcedbname+'.dbo.syscomments c
        join '+@sourcedbname+'.dbo.sysobjects o on c.id=o.id
        where o.xtype in (''V'',''P'',''FN'',''TR'')
        and (text like ''%'+@searchfordbname+'.%''
          or text like ''%'+@searchfordbname+'].%'')'
        print @sql
        exec sp_executesql @sql
        fetch next from curs2 into @searchfordbname
        end
    close curs2
    deallocate curs2
    fetch next from curs into @sourcedbname
    end
close curs
deallocate curs

select * from #XRefDBs
0
Leif Peterson

Toute recherche avec l'instruction select ne donne que le nom d'objet, là où le mot clé de recherche contient. Le moyen le plus simple et le plus efficace est d’obtenir un script de procédure/fonction, puis de rechercher dans un fichier texte généré. Je suis également conforme à cette technique :) Ainsi, vous êtes précis.

0
Nitin Daware

J'utilise celui-ci pour le travail. laisser les [] dans le champ @TEXT, semble vouloir tout renvoyer ...

 SET NOCOUNT ON 

 DECLARE @ TEXT VARCHAR (250) 
 DECLARE @SQL VARCHAR (250) 

 SELECT @ TEXT = '10 .10.100.50 '

 CREATE TABLE #résultats (db VARCHAR (64), nom d'objet VARCHAR (100), xtype VARCHAR (10), définition TEXT) 

 SELECT @TEXT en tant que 'Chaîne de recherche' 
 DECLARE #databases CURSEUR DE SELECT NAME FROM master..sysdatabases où dbid> 4 
 DECLARE @c_dbname varchar (64) 
 OPEN #databases 
 FETCH #databases INTO @c_dbname 
 PENDANT @@ FETCH_STATUS -1 
 COMMENCER
 SELECT @SQL = 'INSERT INTO #results' 
 SELECT @SQL = @SQL + 'SELECT' '' + @c_dbname + '' 'AS db, o.name, o.xtype, m.definition' 
 SELECT @SQL = @SQL + 'FROM'+@c_dbname+'.sys.sql_modules m' 
 SELECT @SQL = @SQL + 'INNER JOIN' + @ c_dbname + '.. sysobjects o ON m.object_id = o.id' 
 SELECT @SQL = @SQL + 'WHERE [définition] LIKE' '%' + @ TEXT + '%' '' 
 EXEC (@SQL) 
 FETCH #databases INTO @c_dbname 
 FIN
 CLOSE #databases 
 DEALLOCATE #databases 

 SELECT * FROM #rdres classés par db, xtype, nom_objet 
 DROP TABLE #results 
0
Christopher Klein

J'ai utilisé ces derniers dans le passé:

Dans ce cas particulier, où vous devez remplacer une chaîne spécifique dans des procédures stockées, le premier lien est probablement plus pertinent.

Le complément Recherche rapide est également utile pour la recherche de noms d’objet avec SQL Server Management Studio. Il existe une version modifiée disponible avec quelques améliorations, et une autre version plus récente également disponible sur Codeplex avec d'autres compléments utiles.

0
Mun
SELECT ROUTINE_TYPE, ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES 
WHERE ROUTINE_DEFINITION LIKE '%Your Text%' 
0
sansalk

Celui-ci, j’ai essayé avec SQL2008, qui permet de chercher en une fois dans toute la base de données.

Create table #temp1 
(ServerName varchar(64), dbname varchar(64)
,spName varchar(128),ObjectType varchar(32), SearchString varchar(64))

Declare @dbid smallint, @dbname varchar(64), @longstr varchar(5000)
Declare @searhString VARCHAR(250)

set  @searhString='firstweek'

declare db_cursor cursor for 
select dbid, [name] 
from master..sysdatabases
where [name] not in ('master', 'model', 'msdb', 'tempdb', 'northwind', 'pubs')



open db_cursor
fetch next from db_cursor into @dbid, @dbname

while (@@fetch_status = 0)
begin
    PRINT 'DB='+@dbname
    set @longstr = 'Use ' + @dbname + char(13) +        
        'insert into #temp1 ' + char(13) +  
        'SELECT @@ServerName,  ''' + @dbname + ''', Name 
        , case  when [Type]= ''P'' Then ''Procedure''
                when[Type]= ''V'' Then ''View''
                when [Type]=  ''TF'' Then ''Table-Valued Function'' 
                when [Type]=  ''FN'' Then ''Function'' 
                when [Type]=  ''TR'' Then ''Trigger'' 
                else [Type]/*''Others''*/
                end 
        , '''+ @searhString +''' FROM  [SYS].[SYSCOMMEnTS]
        JOIN  [SYS].objects ON ID = object_id
        WHERE TEXT LIKE ''%' + @searhString + '%'''

 exec (@longstr)
 fetch next from db_cursor into @dbid, @dbname
end

close db_cursor
deallocate db_cursor
select * from #temp1
Drop table #temp1
0
yenfang chang