在编写查询时是否有快速查看现有列大小的方法?

时间:2015-04-28 08:48:20

标签: sql sql-server sql-server-2008-r2 sql-function

我正在将一些SSRS报告中的大量嵌入式SQL转移到函数中。该过程通常涉及获取当前选择查询,添加INSERT INTO部分并返回结果表。像这样:

CREATE FUNCTION [dbo].[MyReportFunction]
(
    @userid        varchar(255),
    @location      varchar(255),
    more params here...
)

RETURNS @Results TABLE
(
    Title        nvarchar(max),
    Location     nvarchar(255),
    more columns here...
)
AS
BEGIN
    INSERT INTO @Results (Title, Location, more columns...)
    SELECT tblA.Title, tblB.Location, more columns...
    FROM TableA tblA
    INNER JOIN TableB tblB
    ON tblA.Id = tblB.Id
    WHERE tblB.Location = @location

    RETURN

END

作为其中的一部分,我必须将列放入@Results表中,并根据SELECT查询返回的内容为它们提供正确的大小和类型。现在获取类型很好,因为我可以将现有的SELECT查询复制并粘贴到新查询中并将鼠标悬停在列名称上以获取该类型,例如列标题(nvarchar,null)。但是,我还需要知道尺寸。是否有一种简单的方法可以做到这一点,而无需去特定的表并查看列列表?是否有一种方法可以编辑工具提示及鼠标悬停时显示的信息?

如果我有很多连接到不同的表格和一长串的表格滚动,这可能会很烦人。

我正在使用SQL Server 2008 R2

4 个答案:

答案 0 :(得分:2)

您只需查询 INFORMATION_SCHEMA.COLUMNS视图:

SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME IN('TableA', 'TableB')
AND COALESCE(CHARACTER_MAXIMUM_LENGTH, -1) > 0 

我通过将CHARACTER_MAXIMUM_LENGTH的条件添加到结果集来进一步过滤结果 这将只给出具有最大长度的列(varchar,char,nvarchar等) 我希望这会有所帮助。

答案 1 :(得分:1)

正如Zohar建议的那样,您可以使用INFORMATION_SCHEMA.COLUMNS,然后让查询引擎为您做繁重的工作

SELECT TOP 0 * INTO #Temp FROM ( OriginalQuery ) o
SELECT column_name+' ' + 
        data_type + 
        case data_type
            when 'sql_variant' then ''
            when 'text' then ''
            when 'ntext' then ''
            when 'xml' then ''
            when 'decimal' then '(' + cast(numeric_precision as varchar) + ', ' + cast(numeric_scale as varchar) + ')'
            else coalesce('('+case when character_maximum_length = -1 then 'MAX' else cast(character_maximum_length as varchar) end +')','') 
        end +
        case when exists ( 
            select id from syscolumns
            where object_name(id)=TABLE_NAME
            and name=column_name
            and columnproperty(id,name,'IsIdentity') = 1 
            ) then
            ' IDENTITY(' + 
            cast(ident_seed(TABLE_NAME) as varchar) + ',' + 
            cast(ident_incr(TABLE_NAME) as varchar) + ')'
            else ''
        end + 
         (case when IS_NULLABLE = 'No' then ' NOT ' else ' ' end ) + 'NULL' + 
          case when tempdb.INFORMATION_SCHEMA.COLUMNS.COLUMN_DEFAULT IS NOT NULL THEN ' DEFAULT '+ tempdb.information_schema.columns.COLUMN_DEFAULT ELSE '' END + ',' 
FROM tempdb.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME LIKE '#Temp%'
DROP TABLE #TEMP

答案 2 :(得分:1)

由于您的功能似乎只包含rake assets:clobberINSERT ... SELECT,因此您可以将其更改为内嵌TVF。这不会真正回答你提出的问题,但它可能解决了首先需要知道确切数据类型的根本问题:

RETURN

您不仅会因为此切换而不再担心显式数据类型声明,还会获得对查询优化器更透明的函数。如果使用该函数的查询很复杂,而不仅仅是DROP FUNCTION [dbo].[MyReportFunction] -- multi-statement TVF and inline TVF are different object types, -- so ALTER will not work, you have to drop and re-create the object GO CREATE FUNCTION [dbo].[MyReportFunction] ( @userid varchar(255), @location varchar(255), more params here... ) RETURNS TABLE AS RETURN ( SELECT tblA.Title, tblB.Location, more columns... FROM TableA tblA INNER JOIN TableB tblB ON tblA.Id = tblB.Id WHERE tblB.Location = @location ) ,则优化器将能够将函数的查询与主查询混合以获得更好的执行计划。

答案 3 :(得分:0)

使用SQL_VARIANT_PROPERTY

public void setProgress(int currentDuration) {
    // ... Some code to calculate the dirty width
    invalidate(mDirtyWidth,0,mDirtyWidth+ mDirtyWidthRegion, viewHeight);
}

结果可能是:

SELECT top 1
    SQL_VARIANT_PROPERTY(colname, 'BaseType') BaseType, 
    SQL_VARIANT_PROPERTY(colname, 'Precision') [Precision], 
    SQL_VARIANT_PROPERTY(colname, 'Scale') Scale, 
    SQL_VARIANT_PROPERTY(colname, 'MaxLength') [MaxLength]
FROM yourtable
相关问题