2009-06-12 16 views
5

Tengo una UDF que consulta datos de una tabla. La tabla, sin embargo, debe definirse como un parámetro. Por ejemplo, yo no puedo tener:.Usar una variable para el nombre de la tabla en la cláusula 'De' en SQL Server 2008

Select * From [dbo] [TableA]

necesito algo como:.

Select * From [dbo] [@ NombreTabla]

La línea anterior no funciona, y también la UDF me prohíbe configurar la consulta como una cadena y llamar a exec(). Puedo hacer esto en un procedimiento, pero tampoco puedo llamar al procedimiento desde el UDF.

¿Alguien sabe cómo puedo lograr esto dentro de la UDF sin tener algún tipo de declaración de cambio masivo?

+0

Intenté hacer exactamente eso el otro día sin suerte. ¡Espero que alguien lo sepa! – Gabe

Respuesta

7

Esto no se puede hacer, SQL dinámico no es compatible con las funciones.

ver este SO pregunta: Executing dynamic SQL in a SQLServer 2005 function

+0

¡Gracias por el enlace! – DaveK

+1

Esta respuesta es correcta cuando se usan UDF normales (que es lo que pregunté). Pude resolver mi problema con una UDF de CLR escrita en C#. – DaveK

3

puede escribir una UDF CLR que puede hacer SQL dinámico. He tenido que implementar esto antes. Es bastante resbaladizo.

+0

Correcto, pero eso sería una función extendida de CLR, no una UDF? – Andomar

+0

¿Se puede utilizar en una consulta de la misma forma que un UDF? – DaveK

+0

Sí, pero su DBA debe aceptar habilitar el soporte de CLR, y debe implementarlos como .NET compilado. Http://msdn.microsoft.com/en-us/library/ms254498(VS.80).aspx – Andomar

5

Puede UNIONAR TODAS sus tablas e incluir el nombre de la tabla como una columna, luego especifique el nombre de la tabla como un predicado sobre esto. Si comprueba el plan de consulta para este ejemplo, ve que no se toca t2

create table t1 (i int) 
create table t2 (i int) 

insert t1 values(1) 
insert t1 values(2) 
insert t1 values(3) 
insert t2 values(4) 
insert t2 values(5) 
insert t2 values(6) 


;with tableSet as (
    select i, 't1' as tableName from t1 
    union all select i, 't2' as tableName from t2 
) 
select i from tableSet where tableName = 't1' 
+0

+1 la pregunta excluye un enfoque de "declaración de conmutación masiva" aunque – Andomar

+0

@Andomar, pensé que esto era un poco menos "cambiante" que un grupo de bloques if/else. P.ej. este conjunto de tablas para UNION ALL podría verse envuelto en una vista si tenía muchas funciones que necesitaban la funcionalidad, lo que no podría hacer con if/else. Punto tomado;) – ahains

0

No puede hacerlo. ¿Qué problema estás resolviendo? Puede haber otras soluciones.

21
SET @SQL = 'SELECT * FROM ' + @table 
EXEC (@SQL) -- parentheses are required 
+2

Se bueno saber por qué esto obtuvo un voto negativo ... – johnnycrash

+0

Es posible que hayas obtenido un voto negativo porque esto te deja abierto a un ataque de inyección SQL dependiendo de cómo uses esta consulta. EDITAR: Me acabo de dar cuenta de que DaveK dijo que no puede hacer esto en la pregunta. De ahí es de donde vino su voto negativo. –

0

Si desea dar más detalles sobre qué problema subyacente está tratando de resolver, podríamos tener mejores respuestas. Una solución es generar código para las UDF por tabla. Otra es usar SQL dinámico de un SP. Lo que es correcto para su situación es difícil de decir.

Cuestiones relacionadas