【问题标题】:Determine which types require a length specification确定哪些类型需要长度规范
【发布时间】:2016-03-13 08:12:29
【问题描述】:

如何确定一个类型是否需要指定长度? 理想情况下,我想按类型了解这一点。下面@ZoharPeled 提到的INFORMATION_SCHEMA.COLUMNS 按列列出了信息,但它只有与数据库中已经存在的列相对应的类型,而不是所有可能的类型。

在生成动态 SQL 时,直到运行时我才知道其数据类型或名称,我需要创建一个表变量来存储 Inserted.X results

我将查询中的数据类型记录到sys.columns,但是,我还需要指定某些类型的长度。我可以从sys.columns.max_length 获得。但是,某些类型(例如 int)在指定长度时会产生错误(例如 DECLARE @n int(4)),我无法弄清楚如何判断每个类型必须如何声明。

在下面的 SQL 中,namemd5 必须有长度,而Id 必须

DECLARE @_cnb TABLE (Id int, name nvarchar, md5 varbinary);
INSERT INTO dbo._users (name, md5)
OUTPUT Inserted.Id, Inserted.name, Inserted.md5 INTO @_cnb
VALUES (@a,@b) OPTION (MAXDOP 1);
-- Do stuff with contents of table variable

我是如何生成 SQL 的:

我需要能够支持每个主要数据库,因此每个数据库都有一个用于不同操作的模板。正在进行的 MS SQL 插入模板是:

BEGIN
{0}
INSERT INTO {1} ({2})
OUTPUT {3} INTO @_cnb
VALUES ({4}) OPTION (MAXDOP 1);
{5}
END;

然后我填写每个部分。 {1} 是 table.schema,{3} 是“Inserted.FOO, Inserted.BAR”等。

在添加连接表支持之前,之前的模板生成的 SQL 如下:

INSERT INTO _users
    (first_name,last_name,site_id,site_id2,name)
VALUES (@a,@b,@c,@d,@e)

现在(叹气)它看起来更像:

BEGIN
DECLARE @_cnb TABLE (Id int,first_name nvarchar,last_name nvarchar,site_id int,site_id2 int);
INSERT INTO dbo._users (first_name,last_name,site_id,site_id2)
OUTPUT Inserted.Id, Inserted.first_name, Inserted.last_name, Inserted.site_id, Inserted.site_id2 INTO @_cnb
VALUES (@a,@b,@c,@d) OPTION (MAXDOP 1);
INSERT INTO dbo._user_access (user_id,access_id)
SELECT Id,@e FROM @_cnb;
-- others
INSERT INTO dbo._cars2 (user_id,name)
SELECT Id,@n FROM @_cnb;
END;

至于构建{0}{1}等,只是大量的手动字符串操作。

【问题讨论】:

  • 能否补充一些关于为什么要生成动态 sql 的信息,以便了解更多
  • 这类需要长度的类型并不多 - 检查它是否是其中之一并使用 max_length 来完成该动态 sql。还要注意具有精度和小数位数的数字类型。
  • 您可以改用INFROMATION_SCHEMA.COLUMNS,在该视图中,当不应该有内容长度时,CHARACTER_MAXIMUM_LENGTH 列为空,并且当它为最大值时(如在 varchar(max) 或 varbinary(max ) 它声明-1
  • @TheGameiswar:添加了动态 SQL 生成细节
  • @IvanStarostin:这就是我的目标:按类型存储是否需要长度规范。我真的想避免这种情况,因为我需要在添加到每个 DBMS 时添加任何新类型,但这种情况并不经常发生。

标签: sql-server metadata dynamic-sql


【解决方案1】:

您可以改用INFORMATION_SCHEMA.COLUMNS,在该视图中,当不应该有内容长度时,CHARACTER_MAXIMUM_LENGTH 列为空,而当它达到最大值时(如在varchar(max)varbinary(max) 中,它表示 -1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 2011-08-10
    • 2018-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多