查询以存储的prodecure(sp_sqlexec)运行,不会产生任何结果(T-SQL,MS SQL Server)

时间:2017-12-08 10:59:31

标签: sql-server-2008 stored-procedures

我想运行一个查询,显示数据类型为varchar且最大长度为8000个字符的数据库中所有表的所有列。

到目前为止,这是我的代码。

DECLARE @tabs VARCHAR(MAX);
SET @tabs = 
(
  SELECT STUFF(( SELECT DISTINCT ',' + [TABLE_NAME]
                 FROM [DB-Test].INFORMATION_SCHEMA.COLUMNS 
                 WHERE DATA_TYPE = 'VARCHAR' AND
                       CHARACTER_MAXIMUM_LENGTH = 8000
                 FOR XML PATH('')), 1, 1, '')
);

DECLARE @cols VARCHAR(MAX)
SET @cols = 
(
  SELECT STUFF(( SELECT DISTINCT ',' + [TABLE_NAME] + '.' + [COLUMN_NAME]
                 FROM [DB-Test].INFORMATION_SCHEMA.COLUMNS 
                 WHERE DATA_TYPE = 'VARCHAR' AND
                       CHARACTER_MAXIMUM_LENGTH = 8000
                 FOR XML PATH('')), 1, 1, '')
);

DECLARE @query VARCHAR(MAX) = 'SELECT ' + @cols + ' FROM ' + @tabs

EXEC sp_sqlexec @query

当我运行查询时,我得到所有列名,但不是列中的值。它是空的。没有'NULL'值。好像@cols被解释为简单的字符串。 为什么? (当我读出@cols和@tabs时,他们是正确的。)

1 个答案:

答案 0 :(得分:1)

我猜你的数据库中有一个表有VARCHAR数据类型和8000长度的列,但该表没有任何记录。尝试只包括那些至少有一条记录可用的列和表。

你可以在下面试试。检查一下,让我知道它是否有效。

DECLARE @tabs VARCHAR(MAX) = ''

; WITH CTE AS 
(
 SELECT DISTINCT TA.NAME TABLENAME
      , SUM(PA.ROWS) OVER (PARTITION BY TA.NAME ) NOOFROW
 FROM SYS.TABLES TA
 INNER JOIN SYS.PARTITIONS PA ON PA.OBJECT_ID = TA.OBJECT_ID
 INNER JOIN SYS.SCHEMAS SC ON TA.SCHEMA_ID = SC.SCHEMA_ID
 WHERE TA.IS_MS_SHIPPED = 0 AND PA.INDEX_ID IN (1,0) 
), TABLENAME AS
(
    SELECT ITBL.[TABLE_NAME]
    FROM INFORMATION_SCHEMA.COLUMNS ITBL
    WHERE ITBL.DATA_TYPE = 'VARCHAR' AND
          ITBL.CHARACTER_MAXIMUM_LENGTH = 8000  
          AND EXISTS(SELECT 1 FROM CTE WHERE CTE.TABLENAME = ITBL.TABLE_NAME AND CTE.NOOFROW > 0) -- To check no of record available in table
)
SELECT @tabs = @tabs+ISNULL(','+TABLE_NAME, '')
FROM TABLENAME

DECLARE @cols VARCHAR(MAX) = '';

; WITH CTE AS 
(
 SELECT DISTINCT TA.NAME TABLENAME
      , SUM(PA.ROWS) OVER (PARTITION BY TA.NAME ) NOOFROW
 FROM SYS.TABLES TA
 INNER JOIN SYS.PARTITIONS PA ON PA.OBJECT_ID = TA.OBJECT_ID
 INNER JOIN SYS.SCHEMAS SC ON TA.SCHEMA_ID = SC.SCHEMA_ID
 WHERE TA.IS_MS_SHIPPED = 0 AND PA.INDEX_ID IN (1,0) 
), TABLENAME AS
(
    SELECT ITBL.[TABLE_NAME], ITBL.[COLUMN_NAME]
    FROM INFORMATION_SCHEMA.COLUMNS ITBL
    WHERE ITBL.DATA_TYPE = 'VARCHAR' AND
          ITBL.CHARACTER_MAXIMUM_LENGTH = 8000  
          AND EXISTS(SELECT 1 FROM CTE WHERE CTE.TABLENAME = ITBL.TABLE_NAME AND CTE.NOOFROW > 0) -- To check no of record available in table
)
SELECT @cols = @cols+ISNULL(','+[TABLE_NAME]+'.'+[COLUMN_NAME], '')
FROM TABLENAME

IF LEN(@cols) > 0 AND LEN(@tabs) > 0
BEGIN
    DECLARE @query VARCHAR(MAX) = 'SELECT ' + STUFF(@cols,1,1,'') + ' FROM ' + STUFF(@tabs,1,1, '')

    EXEC sp_sqlexec @query  
END
ELSE
BEGIN
    PRINT 'No Column available with data where it''s datatype is VARCHAR and length is 8000'
END