Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

[SOLUCIONADO] [Transact-SQL] Consulta con parámetro en SELECT

Estas en el tema de [Transact-SQL] Consulta con parámetro en SELECT en el foro de SQL Server en Foros del Web. Buenas! Tengo un problema con una consulta Transact-SQL. Resulta que tengo el nombre de una tabla en una variable, y debo ejecutar una consulta con ...
  #1 (permalink)  
Antiguo 22/05/2013, 07:25
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
[Transact-SQL] Consulta con parámetro en SELECT

Buenas!

Tengo un problema con una consulta Transact-SQL. Resulta que tengo el nombre de una tabla en una variable, y debo ejecutar una consulta con esa variable de este estilo:

Código SQL:
Ver original
  1. SELECT @cafe1 = @fieldname FROM #del d
¡Resulta que al ejecutar este código, al final, @cafe1 vale lo mismo que @fieldname! Pero, cuando en vez de @fieldname pongo el nombre de la columna, devuelve el valor que busco, que en este caso sería un valor eliminado en un UPDATE o en un DELETE.

¿Cómo hago para que la consulta tome de forma literal @fieldname? Gracias de antemano!!!

Última edición por gnzsoloyo; 22/05/2013 a las 07:28 Razón: Usar HIGHLIGHT "SQL"
  #2 (permalink)  
Antiguo 22/05/2013, 08:23
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

SELECT @cafe1 = 'fieldname' FROM #del d
o
set @cafe1='fieldname'

el valor literal de lo que buscas no??
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 22/05/2013, 08:32
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

@fieldname tiene dentro texto, que es una columna en este caso. Lo que necesito es poder utilizar literalmente el texto que tiene la variable, dentro de una consulta de asignación.

Lo que logro poniendo 'fieldname' sería que la consulta busque la columna 'fieldname', lo cual no tiene sentido.

¿Puede guardarse el resultado de una instrucción EXECUTE en una variable? Porque es posible armar la cadena de la consulta SQL, y como EXECUTE permite ejecutar consultas almacenadas en variables, quizás es una posible solución si se puede almacenar el resultado en una variable.

Última edición por Xarvastia; 22/05/2013 a las 08:49
  #4 (permalink)  
Antiguo 22/05/2013, 09:14
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

a ya lo que ocupas es una consulta dinamica:

declare @query varchar(max)
set @query='select ' + @fieldname + 'from tabla'
sp_executesql @query

y obtienes lo que necesitas :)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #5 (permalink)  
Antiguo 22/05/2013, 09:33
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Libras;

Tu expresión es idéntica a

Código:
declare @query varchar(max)
set @query='select ' + @fieldname + 'from tabla'
exec (@query)
(Trabajo con SSMS 2008)

Si bien con esto estoy ejecutando tal consulta, necesito almacenar el resultado de esa consulta en una variable. Esto no es posible poniendo SET @variable = exec(@query). Con almacenar el resultado de la consulta, hecha en la variable @query, en otra variable, soluciono mi problema.
  #6 (permalink)  
Antiguo 22/05/2013, 09:39
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

por recomendacion es mejor utilizar sp_executesql que exec aunque el resultado es el mismo, ya no entendi que necesitas, pero dices que funciono bien por ti :)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #7 (permalink)  
Antiguo 22/05/2013, 11:06
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

No, no se solucionó. Lee atentamente mi último post para darte una mejor idea.

Es simple: necesito almacenar en una variable el resultado de una consulta sql almacenada en otra variable.
  #8 (permalink)  
Antiguo 22/05/2013, 11:16
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

o sea quieres almacenar el resultado de una consulta en una variable? esto es correcto? de ser asi porque no usas tablas temporales?? o variables tipo tabla?

o podrias explicar mejor tu problematica(con peras y manzanas estaria genial ;) )
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #9 (permalink)  
Antiguo 22/05/2013, 11:22
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Expliqué muy bien el problema, y evidentemente recién lo entendiste. Es tal cual lo escribiste recién, debo almacenar en una variable el resultado de una consulta SQL, ya que no puedo hacerlo con un SET o SELECT @variable = consulta, porque la columna de la consulta SELECT es una variable.

Si es la única forma, ¿tenés algún ejemplo simple con una tabla temporal en mente que se relacione con mi problema?

Gracias de antemano.
  #10 (permalink)  
Antiguo 22/05/2013, 11:25
Avatar de aid_val  
Fecha de Ingreso: mayo-2013
Ubicación: Guanajuato
Mensajes: 302
Antigüedad: 11 años
Puntos: 5
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Y porque mejor no igualas tu variable a la consulta que necesitas
  #11 (permalink)  
Antiguo 22/05/2013, 11:27
Avatar de aid_val  
Fecha de Ingreso: mayo-2013
Ubicación: Guanajuato
Mensajes: 302
Antigüedad: 11 años
Puntos: 5
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

ejemplo 1 :
SELECT @ACUMULADO_ESTIMACION = SUM(b.CANTIDAD_ESTIMACION) FROM resumen_generador a CROSS JOIN resumen_generador b WHERE (b.id_resumen_generador <= a.id_resumen_generador AND A.id_concepto=@ID_CONCEPTO )GROUP BY a.id_resumen_generador ,a.cantidad_estimacion ORDER BY a.id_resumen_generador ,a.cantidad_estimacion
ejemplo 2:
estimado = (Select SUM(importe_concepto) from resumen_generador where id_estimacion=@ID_ESTIMACION )

Última edición por aid_val; 22/05/2013 a las 11:27 Razón: a
  #12 (permalink)  
Antiguo 22/05/2013, 11:29
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Esto no es posible, ya que la columna es una variable y tal consulta devolvería el valor de la variable, no del valor de la columna, que es lo que estoy buscando. Esto se ha explicado en el primer post.

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

a ver vamos por partes, me supongo que desarrollas verdad? entonces lo que quieres es que un resultado de valores se almacene en una variable de tipo array correcto? en sql server no existen las variables tipo array, porque un array es una coleccion de datos...o sea una tabla :)

en tu ejemplo tienes una tabla que se llama #del

pues para obtener la info en una tabla temporal solo seria

select * into #temp2 from #del

y ya tienes los valores que necesitas en una tabla......


y si quieres obtener los registros de un update o un delete, porque no usas triggers?

ahora todo esto para que lo necesitas puedes explicar mejor tu problematica?
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #14 (permalink)  
Antiguo 22/05/2013, 12:03
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Es un trigger. Con la consulta, debería venir un solo valor, no un array, ya que está en un loop que revisa registro por registro de las tablas #ins (temporal de inserted) y #del (de deleted).

Necesito recuperar ambos valores (eliminado e insertado), para armar una cadena de texto en un campo independiente en una tabla de logs.

Según tus instrucciones, el código quedó de la siguiente manera:

Código:
SET @querycafe1 = 'SELECT ' + @fieldname + ' INTO #temp1 FROM #del d'
SET @querycafe2 = 'SELECT ' + @fieldname + ' INTO #temp2 FROM #ins i'
Exec(@querycafe1)
Exec(@querycafe2)
SET @valorViejo = (SELECT * FROM #temp1) 
SET @valorNuevo = (SELECT * FROM #temp2) 
Sin embargo, las líneas en rojo devuelven un error de "nombre no válido".

Nos estamos acercando! Es nada más resolver el tema en rojo :)

EDIT: La consulta:

SELECT convert(varchar(1000),@fieldname) INTO #temp1 FROM #del d

Devuelve error de sintaxis.

Última edición por Xarvastia; 22/05/2013 a las 12:13
  #15 (permalink)  
Antiguo 22/05/2013, 12:59
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

a ver a ver, si quieres sacar todos los valores de tu "query" en una sola cadena asi no lo vas a lograr tendrias que usar coalesce para hacer eso y aqui esta la solucion a tu problema :)

http://www.codeproject.com/Tips/3344...text-string-us

saludos!
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #16 (permalink)  
Antiguo 22/05/2013, 13:03
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Aclaro: hay un sólo valor en la tabla temporal que devuelve esa consulta, no es necesario concatenar, o un array.

Saludos.
  #17 (permalink)  
Antiguo 22/05/2013, 13:34
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

me lleva....

Código SQL:
Ver original
  1. SET @querycafe1 = 'SELECT ' + @fieldname + ' INTO #temp1 FROM #del d'
  2. SET @querycafe2 = 'SELECT ' + @fieldname + ' INTO #temp2 FROM #ins i'
  3. EXEC(@querycafe1)
  4. EXEC(@querycafe2)
  5. SELECT @valorviejo=campo FROM #temp1
  6. SELECT  @valorNuevo=campo  FROM #temp2
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #18 (permalink)  
Antiguo 23/05/2013, 07:50
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Pero campo es una variable! xD Sigue siendo @fieldname, y no resuelve el problema planteado desde el primer post.
  #19 (permalink)  
Antiguo 23/05/2013, 08:01
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

realmente no te entiendo, como campo va a ser una variable? si ya insertaste en una tabla el "valor" de fieldname entonces en la tabla vas a tener dichos valores, puse lo de "campo" porque no se con que nombre se guardo la columna dentro de la tabla temporal, probaste lo que te puse???
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #20 (permalink)  
Antiguo 23/05/2013, 08:13
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

¿No debería, si la consulta es

SET @querycafe1 = 'SELECT ' + @fieldname + ' INTO #temp1 FROM #del d'

guardarse en una columna llamada @fieldname en la tabla temporal?

Si fuera posible especificar en la tabla temporal, en qué campo se guardará el resultado, tendríamos resuelto el problema, ¿no estás de acuerdo?
  #21 (permalink)  
Antiguo 23/05/2013, 08:18
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

tengo este query y me regresa el campo que se afecta, como lo estas haciendo tu??

Código SQL:
Ver original
  1. CREATE TABLE pruebas
  2. (
  3. id INT,
  4. nombre VARCHAR(20)
  5. )
  6.  
  7. INSERT INTO pruebas VALUES (1,'Libras')
  8. INSERT INTO pruebas VALUES (2,'Yo')
  9. INSERT INTO pruebas VALUES (3,'Tu')
  10. INSERT INTO pruebas VALUES (4,'Mama')
  11. INSERT INTO pruebas VALUES (5,'Nos')
  12.  
  13. UPDATE pruebas
  14. SET nombre='libras'
  15. WHERE id=5
  16. USE testing
  17.  
  18. ALTER TRIGGER tg_pruebas ON pruebas after INSERT,UPDATE
  19. AS
  20. BEGIN
  21. DECLARE @valor INT
  22. DECLARE @id INT
  23. DECLARE @nombre VARCHAR(20)
  24. DECLARE @fieldname VARCHAR(20)
  25. SET @fieldname=''
  26. SET @valor=0
  27. SELECT @valor=COUNT(*) FROM deleted
  28.  
  29. IF @valor>=1
  30.  BEGIN
  31.     --print 'alla'
  32.     SELECT @id=id,@nombre=nombre FROM deleted
  33.     --print @id
  34.     --print @nombre
  35.     --select * from inserted
  36.     IF @id<>(SELECT id FROM inserted)
  37.       SET @fieldname=@fieldname + 'Id'
  38.     IF @nombre<>(SELECT nombre FROM inserted)
  39.       SET @fieldname=@fieldname + 'Nombre'  
  40.    
  41.    
  42.  END
  43. ELSE
  44.  BEGIN
  45.    --print 'aqui'
  46.     SELECT * FROM inserted 
  47.    --select @id=id,@nombre=nombre from deleted
  48.    
  49.  END
  50. IF @fieldname<>''
  51. print 'El campo afectado ' + @fieldname
  52.  
  53. END
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #22 (permalink)  
Antiguo 23/05/2013, 09:34
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Parcial de código de trigger:

Código:
ALTER TRIGGER [dbo].[triggerC] ON [dbo].[Cliente] FOR INSERT, UPDATE, DELETE
AS 

DECLARE @bit int ,    
        @field int ,    
        @maxfield int ,    
        @char int ,    
        @fieldname varchar(128) ,    
        @TableName varchar(128) ,    
        @PKCols varchar(1000) ,    
        @sql varchar(2000),     
        @UpdateDate varchar(21) ,    
        @UserName varchar(128) ,    
        @Type char(1) ,    
        @PKSELECT varchar(1000),
        @cambios varchar(MAX),
        @fielddCambios varchar(MAX),
        @fieldiCambios varchar(MAX)
    
SELECT @TableName = 'Cliente' --<-- cambiar el nombre de la tabla 

-- Fecha y Usuario
SELECT @UserName = system_user ,
       @UpdateDate = convert(varchar(8), getdate(), 112) + 
                     ' ' + 
                     convert(varchar(12), getdate(), 114)

SET NoCount ON 

-- Identificar que evento se está ejecutando (Insert, Update o Delete) 
--en base a cursores especiales (inserted y deleted)
if exists (SELECT * FROM inserted) 
  if exists (SELECT * FROM deleted) --Si es un update
    SELECT @Type = 'U'
  else                              --Si es un insert
    SELECT @Type = 'I'
else                                --si es un delete
    SELECT @Type = 'D'
    
-- Obtenemos la lista de columnas de los cursores
SELECT * INTO #ins FROM inserted
SELECT * INTO #del FROM deleted
    
-- Obtener las columnas de llave primaria
SELECT @PKCols = coalesce(@PKCols + ' and', ' on') + 
       ' i.' + 
       c.COLUMN_NAME + ' = d.' + 
       c.COLUMN_NAME
 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk
  JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
  ON c.TABLE_NAME = pk.TABLE_NAME
  AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
 WHERE pk.TABLE_NAME = @TableName AND 
  pk.CONSTRAINT_TYPE = 'PRIMARY KEY'
    
-- Obtener la llave primaria y columnas para la inserción en la tabla de auditoria
SELECT 
 @PKSELECT = coalesce(@PKSelect+'+','') + 
 '''<' + 
 COLUMN_NAME + 
 '=''+convert(varchar(100),coalesce(i.' + 
 COLUMN_NAME +',d.' + 
 COLUMN_NAME + '))+''>''' 
 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk  
 JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
  ON c.TABLE_NAME = pk.TABLE_NAME
  AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
 WHERE pk.TABLE_NAME = @TableName
  AND CONSTRAINT_TYPE = 'PRIMARY KEY'
    
if @PKCols is null --<-- Este trigger solo funciona si la tabla tiene llave primaria
 BEGIN
  RAISERROR('no PK on table %s', 16, -1, @TableName)
  RETURN
 END
    
--Loop para armar el query de inserción en la tabla de log. 
--Un registro por cada campo afectado.
SELECT 
 @field = 0, 
 @maxfield = max(ORDINAL_POSITION) 
 FROM INFORMATION_SCHEMA.COLUMNS 
 WHERE TABLE_NAME = @TableName
    
while @field < @maxfield
 BEGIN
  SELECT @field = min(ORDINAL_POSITION) 
   FROM INFORMATION_SCHEMA.COLUMNS 
   WHERE TABLE_NAME = @TableName and ORDINAL_POSITION > @field
  SELECT @bit = (@field - 1 )% 8 + 1
  SELECT @bit = power(2,@bit - 1)
  SELECT @char = ((@field - 1) / 8) + 1
  if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in ('I','D')
   BEGIN
     SELECT @fieldname = COLUMN_NAME 
      FROM INFORMATION_SCHEMA.COLUMNS 
      WHERE TABLE_NAME = @TableName and ORDINAL_POSITION = @field
     
     DECLARE         
     @querycafe1 nvarchar(MAX),
     @querycafe2 nvarchar(MAX),
     @valorViejo varchar(MAX),     
     @valorNuevo varchar(MAX)
     
     SET @querycafe1 = 'SELECT ' + @fieldname + ' INTO #temp1 FROM #del d'
     SET @querycafe2 = 'SELECT ' + @fieldname + ' INTO #temp2 FROM #ins i'
     Exec(@querycafe1)
     Exec(@querycafe2)
     --NO FUNCIONAN
     SET @valorViejo = (SELECT[*] FROM #temp1) 
     SET @valorNuevo = (SELECT[*] FROM #temp2)
     
     --Esto es lo que hay que armar, una cadena de texto.
     SELECT @cambios = @cambios + ', ' + @fieldname + ' de ' --+ ' convert(varchar(1000),d.' + @fieldname + ') a ' + ' convert(varchar(1000),i.' + @fieldname + ')' 
  #23 (permalink)  
Antiguo 23/05/2013, 10:19
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

para empezar ese query no es tuyo o si?? ;), a mi me funciono una auditoria parecida a la que te puse en el ejemplo digo un poco rudimentaria(eso de usar ifs y demas) pero funcional y entendible jejeje, con el codigo entiendo que es lo que quieres lograr :)

y aqui esta la respuesta :)

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

Ojo estoy usando una tabla llamada pruebas adecualo a tus necesidades
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #24 (permalink)  
Antiguo 23/05/2013, 10:40
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

El 90% del código no es mío.

Genial, ahí armás y ejecutás un procedimiento @query que lo que haría es armar la cadena que estoy buscando.

Esa cadena, ¿cómo la recupero?

Es lo único que falta para marcar esto como solucionado.

Un abrazo.
  #25 (permalink)  
Antiguo 23/05/2013, 11:13
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 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
  #26 (permalink)  
Antiguo 23/05/2013, 11:33
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Si, entiendo por qué armaste así la cadena y entiendo lo que hace el procedimiento, era la sintaxis lo que me tenía con problemas.

Lo pruebo y te cuento. Gracias por tu tiempo!
  #27 (permalink)  
Antiguo 23/05/2013, 23:33
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

y al final funciono o no???
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #28 (permalink)  
Antiguo 24/05/2013, 05:23
 
Fecha de Ingreso: mayo-2013
Mensajes: 16
Antigüedad: 11 años
Puntos: 0
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

El problema fue resuelto. Muchísimas gracias por tu tiempo, sabés de esto aunque nos costó entendernos. El parámetro OUTPUT fue la clave.
  #29 (permalink)  
Antiguo 24/05/2013, 09:48
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 16 años, 9 meses
Puntos: 180
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

29 postas y todo por un parametro de tipo OUTPUT????
__________________
MCTS Isaias Islas
  #30 (permalink)  
Antiguo 24/05/2013, 10:04
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: [Transact-SQL] Consulta con parámetro en SELECT

Cita:
Iniciado por iislas Ver Mensaje
29 postas y todo por un parametro de tipo OUTPUT????
la verdad no solo fue un parametro output fue entender lo que necesitaba quien preguntaba, acomodar la cadena de impresion en el formato que queria y para terminar el parametro output.....pero para el solo fue...el output fue lo que resolvio gracias jajajajaja
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Etiquetas: bases-de-datos-general, select, sql, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 08:43.