sql >> Base de Datos >  >> RDS >> Sqlserver

sp_MSForEachDB Uso no válido del operador de efecto secundario dentro de la función

No puede hacer esto dinámicamente (como sin codificar todos los nombres de la base de datos por adelantado) sin SQL dinámico, y no puede usar SQL dinámico en una función. Usted no debería usar sp_MSForEachDB en ningún caso o, en mi humilde opinión, usando INFORMACION_ESQUEMA .

Escriba un procedimiento almacenado que devuelva el conjunto de resultados. Si es absolutamente necesario unir la salida a otras cosas (¿por qué no codificar eso en el procedimiento almacenado?), luego inserte la salida en una tabla #temp.

Prueba esto:

CREATE PROCEDURE dbo.AllMyColumnsEverywhereForReals
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @sql NVARCHAR(MAX) = N'';

  SELECT @sql += '
  UNION ALL SELECT 
      [database]  = N''' + d.name + ''' COLLATE SQL_Latin1_General_CP1_CI_AI,
      [schema]    = s.name COLLATE SQL_Latin1_General_CP1_CI_AI,
      [object]    = o.name COLLATE SQL_Latin1_General_CP1_CI_AI,
      [column]    = c.name COLLATE SQL_Latin1_General_CP1_CI_AI,
      [qualified] = QUOTENAME(''' + d.name + ''') 
        + ''.'' + QUOTENAME(s.name) 
        + ''.'' + QUOTENAME(c.name) COLLATE SQL_Latin1_General_CP1_CI_AS,
      [type] = CASE o.type WHEN ''U'' THEN ''Table'' ELSE ''View'' END
    FROM ' + QUOTENAME(d.name) + '.sys.columns AS c
      INNER JOIN ' + QUOTENAME(d.name) + '.sys.objects AS o
      ON c.[object_id] = o.[object_id]
      INNER JOIN ' + QUOTENAME(d.name) + '.sys.schemas AS s
      ON o.[schema_id] = s.[schema_id]
      WHERE o.type IN (''U'', ''V'')'
  FROM sys.databases AS d WHERE [state] = 0 AND name NOT IN 
    (N'master',N'tempdb',N'msdb',N'model',N'ReportServer',N'ReportServerTempDB');

  SET @sql = STUFF(@sql, 1, 13, '');

  EXEC sp_executesql @sql;
END
GO

Uso:

CREATE TABLE #x
(
  db     SYSNAME, 
  sch    SYSNAME, 
  obj    SYSNAME, 
  col    SYSNAME, 
  qual   NVARCHAR(390),
  [type] CHAR(5)
);

INSERT #x EXEC dbo.AllMyColumnsEverywhereForReals;

SELECT cols FROM #x AS x -- INNER JOIN something else ON x.whatever...