una - ¿Cómo encontrar un texto dentro de los procedimientos/activadores de SQL Server?
buscar una tabla en todas las bases de datos (13)
Cualquier búsqueda con una declaración seleccionada produce solo el nombre del objeto, donde contiene la palabra clave de búsqueda. La forma más fácil y eficiente es obtener un script de procedimiento / función y luego buscar en el archivo de texto generado, también sigo esta técnica :) Así que eres el punto exacto.
Tengo un linkedserver que cambiará. Algunos procedimientos llaman al servidor vinculado así: [10.10.100.50].dbo.SPROCEDURE_EXAMPLE
. También tenemos factores desencadenantes que hacen este tipo de trabajo. Necesitamos encontrar todos los lugares que usan [10.10.100.50]
para cambiarlo.
En SQL Server Management Studio Express, no encontré una característica como "encontrar en toda la base de datos" en Visual Studio. ¿Puede un sys-select especial ayudarme a encontrar lo que necesito?
Este lo intenté en SQL2008, que puede buscar desde todos los db de una vez.
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
Esto funcionará para ti:
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
Hay soluciones mucho mejores que modificar el texto de sus procedimientos almacenados, funciones y vistas cada vez que cambia el servidor vinculado. Aquí hay algunas opciones:
Actualiza el servidor vinculado. En lugar de utilizar un servidor vinculado nombrado con su dirección IP, cree un nuevo servidor vinculado con el nombre del recurso como
Finance
oDataLinkProd
o algo así. Luego, cuando necesite cambiar a qué servidor se llega, actualice el servidor vinculado para que apunte al nuevo servidor (o suéltelo y vuelva a crearlo).Aunque lamentablemente no puede crear sinónimos para servidores o esquemas vinculados, PUEDE crear sinónimos para objetos que se encuentran en servidores vinculados. Por ejemplo, su procedimiento
[10.10.100.50].dbo.SPROCEDURE_EXAMPLE
podría por alias. Tal vez cree un esquemadatalinkprod
, luegoCREATE SYNONYM datalinkprod.dbo_SPROCEDURE_EXAMPLE FOR [10.10.100.50].dbo.SPROCEDURE_EXAMPLE;
. Luego, escriba un procedimiento almacenado que acepte un nombre de servidor vinculado, que consulte todos los objetos potenciales de la base de datos remota y (re) cree sinónimos para ellos. Todos sus SP y funciones se reescriben una sola vez para usar los nombres de sinónimos que comienzan condatalinkprod
, y después de eso, para cambiar de un servidor vinculado a otro, simplementeEXEC dbo.SwitchLinkedServer ''[10.10.100.51]'';
y en una fracción de segundo estás usando un servidor vinculado diferente.
Puede haber aún más opciones. Recomiendo usar las técnicas superiores de preprocesamiento, configuración o indirección en lugar de cambiar las escrituras escritas por humanos. Actualizar automáticamente los scripts creados por la máquina es correcto, esto es un preprocesamiento. Hacer cosas manualmente es horrible.
Los he usado en el pasado:
- Búsqueda de todos los procedimientos almacenados por el usuario para un nombre de tabla
- Buscar y reemplazar datos de SQL Server en todas las columnas de todas las tablas
En este caso particular, donde necesita reemplazar una cadena específica a través de procedimientos almacenados, el primer enlace es probablemente más relevante.
Un poco fuera de tema, el complemento Búsqueda rápida también es útil para buscar nombres de objetos con SQL Server Management Studio. Hay una versión modificada disponible con algunas mejoras, y otra versión más nueva también está disponible en Codeplex con algunos otros complementos útiles también.
Puede buscar dentro de las definiciones de todos los objetos de la base de datos utilizando el siguiente SQL:
SELECT
o.name,
o.id,
c.text,
o.type
FROM
sysobjects o
RIGHT JOIN syscomments c
ON o.id = c.id
WHERE
c.text like ''%text_to_find%''
Puedes encontrarlo como
SELECT DISTINCT OBJECT_NAME(id) FROM syscomments WHERE [text] LIKE ''%User%''
Enumerará distintos nombres de procedimientos almacenados que contienen texto como ''Usuario'' dentro del procedimiento almacenado. Más información
Yo uso este para el trabajo. deje el [] en el campo @TEXT, parece querer devolver todo ...
SET NOCOUNT ON DECLARE @TEXT VARCHAR(250) DECLARE @SQL VARCHAR(250) SELECT @TEXT=''10.10.100.50'' CREATE TABLE #results (db VARCHAR(64), objectname VARCHAR(100),xtype VARCHAR(10), definition TEXT) SELECT @TEXT as ''Search String'' DECLARE #databases CURSOR FOR SELECT NAME FROM master..sysdatabases where dbid>4 DECLARE @c_dbname varchar(64) OPEN #databases FETCH #databases INTO @c_dbname WHILE @@FETCH_STATUS -1 BEGIN 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 [definition] LIKE ''''%''+@TEXT+''%'''''' EXEC(@SQL) FETCH #databases INTO @c_dbname END CLOSE #databases DEALLOCATE #databases SELECT * FROM #results order by db, xtype, objectname DROP TABLE #results
aquí hay una parte de un procedimiento que uso en mi sistema para encontrar texto ...
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
[Respuesta tardía pero con suerte útil]
El uso de tablas del sistema no siempre proporciona resultados correctos al 100% porque es posible que algunos procedimientos almacenados y / o vistas estén encriptados, en cuyo caso deberá usar la conexión DAC para obtener los datos que necesita.
Recomiendo usar una herramienta de terceros, como ApexSQL Search, que pueda tratar fácilmente los objetos cifrados.
La tabla del sistema Syscomments dará un valor nulo para la columna de texto en caso de que el objeto esté encriptado.
-- 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'');
SELECT ROUTINE_TYPE, ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE ''%Your Text%''
select text
from syscomments
where text like ''%your text here%''