2009-12-11 36 views
5

Tengo algunos procedimientos almacenados complejos que extraen datos de otras bases de datos utilizando servidores vinculados. Estos datos se colocan en tablas temporales que se unen en una consulta de selección para la salida. Los procedimientos funcionan bien pero en el estudio visual si trato de agregar el procedimiento almacenado a un conjunto de datos usando el diseñador obtengo el error nombre de objeto inválido #tmp o lo que sea que se llame a la primera tabla temporal. No puede recuperar el esquema de la base de datos. Es lo mismo para usar y sqldatasource en ASP.NET.Recuperar el esquema de los campos en Visual Studio del procedimiento almacenado que usa tablas temporales

El procedimiento todavía se puede usar, pero tengo que agregar manualmente todas las columnas que debe enviar a la tabla de datos. Esto va a ser una tarea difícil y supongo que tiene que ver con la forma en que Visual Studio reúne los campos de salida del procedimiento almacenado, no parece funcionar de la manera normal. ¿Hay alguna manera de corregir esto, ya que tengo muchas de estas cosas que hacer y no quiero tener que agregar todas las columnas manualmente, lo que consume mucho tiempo y es propenso a errores.

+0

¿Hay algún motivo por el que no pueda usar una función de valor de tabla en lugar de un procedimiento almacenado? – Wilhelm

+0

Sí, no puede usar SQL dinámico o openquery en una función hasta donde yo sé. Corrígeme si estoy equivocado. – PeteT

+0

Respondí mi propia pregunta después de mucha más investigación. Hay una solución extraña. – PeteT

Respuesta

12

Tras Google durante un tiempo he encontrado una solución extraña poner:

IF 1=0 BEGIN 
SET FMTONLY OFF 
END 

Al comienzo de su procedimiento almacenado permite al diseñador para obtener correctamente la información del esquema. Este código obviamente nunca se ejecuta pero resuelve el problema. FMTONLY está relacionado con solo devolver metadatos sobre un procedimiento almacenado. Estoy utilizando SQL Server 2005.

+1

¡ADVERTENCIA! Tenga en cuenta que cuando hace esto, el procedimiento almacenado se ejecutará y se comprometerá por completo cada vez que el diseñador de Visual Studio lo compruebe. Si tiene alguna instrucción update/delete/insert en su proc, se ejecutarán. Solo use esto en procedimientos que solo devuelven datos. De lo contrario, este es un excelente hallazgo! –

0

La razón por la que no puede leer los metadatos es porque tiene una tabla #Temp y no puede encontrar la tabla temporal. Usted puede tratar de conseguir alrededor de él mediante la definición de los metadatos mediante una consulta TOP 0

SELECT TOP 0 
    CONVERT (NULL, VarChar (30)) AS Column1, 
    CONVERT (NULL, INTEGER) AS Column2, 
    CONVERT (NULL, DECIMAL (9, 2)) AS Column3, 
    CONVERT (NULL, VarChar (55)) AS Column4 

UNION 

SELECT * 
FROM #MyTempTable 
+0

Semejantes a eso tomará casi tanto tiempo, no veo por qué el estudio visual no puede obtener los metadatos ejecutando la consulta de forma normal ya que, por ejemplo, Crystal Report puede hacer esto sin problemas. – PeteT

0

La razón por la que no puede obtener los metadatos aquí es porque podría depender de los datos. Por ejemplo.

If Exists(Select 1 From Table Where Column1 = 7) 
    Select Col1, Col2 From Table2 
Else 
    Select Col3, Col4, Col5 From Table2 

Yo nunca escribir un procedimiento almacenado que tiene un número diferente de columnas en función de los datos, pero es posible hacerlo. Solo por un momento, supongamos que tienes un procedimiento almacenado como este. ¿Qué columna de lista debería ser devuelta?

+0

Sí, lo entiendo y nunca escribiría uno donde arrojaría potencialmente un número diferente de columnas. Pero ¿por qué no solo recupera las columnas para las variables que especifico? – PeteT

+0

Porque aún puede no ser determinista. Tenga en cuenta también que un procedimiento almacenado podría devolver ningún conjunto de registros, un conjunto de registros o incluso varios conjuntos de registros. También puede usar funciones de números aleatorios para que cada llamada devuelva columnas diferentes. –

+0

Sí, pero solo se está utilizando para el diseñador, el desarrollador sabe qué columnas deben existir, al final es más rápido para que las coloque en función de los valores que le da al proceso almacenado. Un ejemplo es Crystal Report. Toma los valores que le das y extrae la última tabla de datos que te da un procedimiento almacenado. No importa el hecho de que no existan en tiempo de ejecución, ya que este siempre es el caso, ya que podría cambiar fácilmente cualquier consulta SQL. – PeteT

2

Esto funciona para mí:

SET FMTONLY OFF

No sé por qué alguien puso en SI 1 = 0 en el otro post? ¡Creo que fue solo para demostrar que cuando FMTONLY está activado, se ejecutan todas las condiciones en las declaraciones IF/ELSE!

FMTONLY suele ser activado por aplicaciones como SSRS y Visual Studio al actualizar la información de esquema para una stp. Con FMTONLY en que no se ejecutan las declaraciones, solo se devuelven los nombres de las columnas. El problema es que debido a que no se ejecutan sentencias, la tabla temporal no se crea y, por lo tanto, las columnas devueltas por cualquier instrucción select en la tabla temporal son desconocidas.

El ajuste FMTONLY ON hará que la STP se ejecute por completo. SI tiene alguna instrucción de inserción/actualización/eliminación en su stp, se ejecutarán, por lo tanto, capture el estado de FMTONLY antes de apagarlo y tome las medidas adecuadas para evitar actualizaciones.

Puede determinar si FMTONLY está activado comprobando si 1 = 0. Si lo hace, entonces FMTONLY está activado y puede ejecutar simplemente una selección de las columnas que su stp normalmente devuelve.

Cuestiones relacionadas