我有一个计算列,它使用标量值函数来评估它的值.我需要Persisted根据某些原因制作专栏并且要做到这一点,我需要使该功能具有确定性.我使用如下的查询来获取列类型:
SELECT
@dataType = DATA_TYPE
FROM
INFORMATION_SCHEMA.COLUMNS (NOLOCK)
WHERE
TABLE_SCHEMA = 'X' AND
TABLE_NAME = @TableName AND
COLUMN_NAME = @ColumnName
Run Code Online (Sandbox Code Playgroud)
当我尝试向WITH SCHEMABINDING函数添加子句(使其成为确定性)时,我收到以下错误:
无法模式绑定函数'X.MY_FUNCTION',因为它引用了系统对象'INFORMATION_SCHEMA.COLUMNS'.
如何以确定的方式获取列的类型?我查看了COLUMNPROPERTY和其他元数据函数,但找不到在不使用系统对象的情况下获取列类型的方法.
你可以尝试这样的事情,但我不确定这是否有帮助......
SELECT o.name,c.name,t.name,c.max_length,c.precision,c.is_nullable
FROM sys.columns AS c
INNER JOIN sys.objects AS o ON c.object_id=o.object_id
INNER JOIN sys.types AS t ON c.system_type_id=t.system_type_id
WHERE o.name=@YourTableName
AND c.name=@YourColumnName
Run Code Online (Sandbox Code Playgroud)
还没人给出答案...似乎没有通用的方法...
所以想一想:
DECLARE @cmd VARCHAR(MAX);
WITH AllColumns AS
(
SELECT c.TABLE_NAME AS tbl
,c.COLUMN_NAME AS col
,c.DATA_TYPE AS tp
FROM INFORMATION_SCHEMA.COLUMNS AS c
)
SELECT @cmd=REPLACE
('CASE @tablename '
+ (SELECT ' WHEN ''' + c1.tbl + ''' THEN \n'
+(
SELECT 'CASE @columnname \n'
+ (
SELECT ' WHEN ''' + c2.col + ''' THEN ''' + c2.tp + '''\n'
FROM AllColumns AS c2
WHERE c2.tbl=c1.tbl
FOR XML PATH('')
)
+ ' END'
)
FROM AllColumns AS c1
GROUP BY c1.tbl
FOR XML PATH(''))
+ ' END','\n',CHAR(13)+CHAR(10));
--DROP FUNCTION GetColumnType;
SET @cmd='CREATE FUNCTION GetColumnType(@tablename VARCHAR(250),@columnname VARCHAR(250)) ' + CHAR(13) + CHAR(10)
+ 'RETURNS TABLE AS RETURN ' + CHAR(13) + CHAR(10)
+ 'SELECT @tablename AS TableName,@columnname AS ColumnName,' + @cmd + ' AS DataType;';
EXEC(@cmd);
GO
SELECT * FROM GetColumnType('SomeTable','SomeColumn');
Run Code Online (Sandbox Code Playgroud)
这将创建一个包含您需要的所有类型的内联 TVF 。每当您更改数据库的结构时,您都会DROP FUNCTION再次运行此脚本(首先),一切都会恢复正常。