出现哪些问题,将所有 varchar 参数的大小声明为存储过程中的最大值?

ber*_*d_k 5 sql-server-2005 varchar t-sql

这个问题,似乎其他网站也有随着时间的推移增加列大小的问题。

仅增加表中列的大小是一项相当简单的任务。

但是,当您的商店遵守存储过程参数的长度必须与相应表列的长度相匹配的规则时,通过您的存储过程进行的大量更改就会下降。

锁定在 Oracle 显示,该过程不需要知道 varchar2 参数的长度。

当您将每个 varchar 参数声明为 varchar(max) 或 nvarchar(max) 时,其优缺点是什么?

显然,您可以忘记每次增加色谱柱尺寸时都必须调整程序的维护噩梦。

对 SQLRockStar 的回答: 我想保留一个相当保守的表设计,其中已知长度有限的字段根据当前限制建模,而不为将来可能的扩展保留。

我的许多表都包含一个 id int、一个代码 varchar(30) 和一个描述列 varchar(255)。

代码字段必须反映不同客户的本地命名约定。

一些客户需要将此字段增加到 50。

当我不将长度编码到程序参数中时,我只需要调整这个单一客户的表列。

当我坚持将长度编码到参数中时,那么我要么支持不同客户的不同版本的程序,要么我不得不更改并将更改推出给所有客户。

例子

-- SQL Server
Create Table dbo.SQLServerTable (
    id int identity(1,1) primary key not null,
    code varchar(30) not null,
    description varchar(255) not null
);
go
Create Procedure WrapInsertSQLServer1 (
    @code varchar(30),
    @description varchar(255)
) as
INSERT INTO SQLServerTable values (@code, @description);
go      

Create Procedure WrapInsertSQLServer2 (
    @code varchar(100),
    @description varchar(1000)
) as
INSERT INTO SQLServerTable values (@code, @description);
go      
Run Code Online (Sandbox Code Playgroud)

注意:当你在SQLServerTable中增加某个字符的长度时,你需要调整WrapInsertSQLServer1,但WrapInsertSQLServer2不需要改变。

-- Oracle
Create Table OracleTable (
    id NUMBER(10) primary key not null,
    code varchar2(30) not null,
    description varchar2(255) not null
)
/
CREATE SEQUENCE S_OT START WITH 1
/

Create OR Replace Procedure WrapInsertOracle (
    p_code varchar2,
    p_description varchar2
) as
begin
INSERT INTO OracleTable values (S_OT.NEXTVAL, p_code, p_description);
end;
/   
Run Code Online (Sandbox Code Playgroud)

这里存储过程的参数永远没有长度。

如果你说 WrapInsertSQLServer2 不行 => 你是说 Oracle 本质上是错误的

小智 1

最大的弊端是这些字段被滥用于其他目的而不是其本来的用途。通常尺寸在这里是有原因的。这个问题看起来有点像过去 COBOL 时代经常发生的情况,开发人员会问:你不能只提供 1 个记录类型和 1 个大尺寸字符类型字段吗?这样做(旧的 cobol 填充字段方式)会使关系数据库的含义不太清晰。另一个问题是:在没有注意到的情况下向字符串添加长度的编程错误怎么办?这将产生大量额外空间。存储仍然是有成本的。如果开发人员没有犯错误并且用法保持定义的那样,我认为将 [n]varchar2 字段的长度设置为比当前需要的稍长一点没有坏处。特别是如果可以预见内容的大小将会增长,那么预先定义该内容将节省大量时间。