Ver Mensaje Individual
  #25 (permalink)  
Antiguo 23/05/2013, 11:13
Avatar de Libras
Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 18 años, 4 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

90% del codigo? yo diria un 99% jejejee

Código SQL:
Ver original
  1. ALTER TRIGGER [dbo].[triggerC] ON pruebas FOR INSERT, UPDATE, DELETE
  2. AS
  3.  
  4. DECLARE @bit INT ,    
  5.         @FIELD INT ,    
  6.         @maxfield INT ,    
  7.         @CHAR INT ,    
  8.         @fieldname VARCHAR(128) ,    
  9.         @TableName VARCHAR(128) ,    
  10.         @PKCols VARCHAR(1000) ,    
  11.         @SQL VARCHAR(2000),    
  12.         @UpdateDate VARCHAR(21) ,    
  13.         @UserName VARCHAR(128) ,    
  14.         @TYPE CHAR(1) ,    
  15.         @PKSELECT VARCHAR(1000),
  16.         @cambios VARCHAR(MAX),
  17.         @fielddCambios VARCHAR(MAX),
  18.         @fieldiCambios VARCHAR(MAX)
  19.    
  20. SELECT @TableName = 'pruebas' --<-- cambiar el nombre de la tabla
  21.  
  22. -- Fecha y Usuario
  23. SELECT @UserName = system_user ,
  24.        @UpdateDate = CONVERT(VARCHAR(8), getdate(), 112) +
  25.                      ' ' +
  26.                      CONVERT(VARCHAR(12), getdate(), 114)
  27.  
  28. SET NoCount ON
  29.  
  30. -- Identificar que evento se está ejecutando (Insert, Update o Delete)
  31. --en base a cursores especiales (inserted y deleted)
  32. IF EXISTS (SELECT * FROM inserted)
  33.   IF EXISTS (SELECT * FROM deleted) --Si es un update
  34.     SELECT @TYPE = 'U'
  35.   ELSE                              --Si es un insert
  36.     SELECT @TYPE = 'I'
  37. ELSE                                --si es un delete
  38.     SELECT @TYPE = 'D'
  39.    
  40. -- Obtenemos la lista de columnas de los cursores
  41. SELECT * INTO #ins FROM inserted
  42. SELECT * INTO #del FROM deleted
  43.    
  44. -- Obtener las columnas de llave primaria
  45. SELECT @PKCols = COALESCE(@PKCols + ' and', ' on') +
  46.        ' i.' +
  47.        c.COLUMN_NAME + ' = d.' +
  48.        c.COLUMN_NAME
  49.  FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk
  50.   JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
  51.   ON c.TABLE_NAME = pk.TABLE_NAME
  52.   AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
  53.  WHERE pk.TABLE_NAME = @TableName AND
  54.   pk.CONSTRAINT_TYPE = 'PRIMARY KEY'
  55.    
  56. -- Obtener la llave primaria y columnas para la inserción en la tabla de auditoria
  57. SELECT
  58.  @PKSELECT = COALESCE(@PKSelect+'+','') +
  59.  '''<' +
  60.  COLUMN_NAME +
  61.  '=''+convert(varchar(100),coalesce(i.' +
  62.  COLUMN_NAME +',d.' +
  63.  COLUMN_NAME + '))+''>'''
  64.  FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk  
  65.  JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
  66.   ON c.TABLE_NAME = pk.TABLE_NAME
  67.   AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
  68.  WHERE pk.TABLE_NAME = @TableName
  69.   AND CONSTRAINT_TYPE = 'PRIMARY KEY'
  70.  
  71.    
  72. IF @PKCols IS NULL --<-- Este trigger solo funciona si la tabla tiene llave primaria
  73.  BEGIN
  74.   RAISERROR('no PK on table %s', 16, -1, @TableName)
  75.   RETURN
  76.  END
  77.    
  78. --Loop para armar el query de inserción en la tabla de log.
  79. --Un registro por cada campo afectado.
  80. SELECT
  81.  @FIELD = 0,
  82.  @maxfield = MAX(ORDINAL_POSITION)
  83.  FROM INFORMATION_SCHEMA.COLUMNS
  84.  WHERE TABLE_NAME = @TableName
  85.    
  86. while @FIELD < @maxfield
  87.  BEGIN
  88.   SELECT @FIELD = MIN(ORDINAL_POSITION)
  89.    FROM INFORMATION_SCHEMA.COLUMNS
  90.    WHERE TABLE_NAME = @TableName AND ORDINAL_POSITION > @FIELD
  91.   SELECT @bit = (@FIELD - 1 )% 8 + 1
  92.   SELECT @bit = POWER(2,@bit - 1)
  93.   SELECT @CHAR = ((@FIELD - 1) / 8) + 1
  94.   IF SUBSTRING(COLUMNS_UPDATED(),@CHAR, 1) & @bit > 0 OR @TYPE IN ('I','D')
  95.    BEGIN
  96.      SELECT @fieldname = COLUMN_NAME
  97.       FROM INFORMATION_SCHEMA.COLUMNS
  98.       WHERE TABLE_NAME = @TableName AND ORDINAL_POSITION = @FIELD
  99.   --   print @fieldname
  100.        
  101.      --Esto es lo que hay que armar, una cadena de texto.*/
  102.      DECLARE @query Nvarchar(MAX)
  103.      SET @cambios=''
  104.      DECLARE @cadena Nvarchar(100)
  105.      --SELECT @cambios = @cambios + ', ' + @fieldname + ' de ' + ' convert(varchar(1000),d.' + @fieldname + ') a ' + ' convert(varchar(1000),i.' + @fieldname + ')'  from #ins as i full outer join
  106.      SET @cadena=''
  107.      SET @query='
  108.     select  @salida=' + CHAR(39)  +  @fieldname + 'cambio de ' + CHAR(39) + ' + convert(varchar(1000),d.' + @fieldname + ') + ' + CHAR(39) + ' a ' + CHAR(39) + ' + convert(varchar(1000),i.' + @fieldname + ')' + ' from #ins i full outer join #del d ' + @PKCols
  109.      + ' where i.' + @fieldname + '<> d.' + @fieldname
  110.      
  111.     -- print @query
  112. EXECUTE sp_executesql @query,N'@salida varchar(100) output',@salida=@cadena output
  113. IF  @cadena=''
  114.  print 'Sin cambios'
  115. ELSE
  116.  print @cadena
  117.  
  118.  
  119.      
  120. END    
  121. END

ahi esta el resultado del query en una variable @cadena ;) esto resuelve tu problema???

Pregunta, entiendes que hace este procedure?? y porque arme la cadena de la forma que lo hice??
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Última edición por Libras; 23/05/2013 a las 11:28