SQL Server 静默截断存储过程中的 varchar

2023-11-30

根据本次论坛讨论,SQL Server(我使用的是 2005,但我收集这也适用于 2000 和 2008)默默地截断任何varchar您将 varchar 的长度指定为存储过程参数,即使直接使用INSERT实际上会导致错误。例如。如果我创建这个表:

CREATE TABLE testTable(
    [testStringField] [nvarchar](5) NOT NULL
)

然后当我执行以下命令时:

INSERT INTO testTable(testStringField) VALUES(N'string which is too long')

我收到错误:

String or binary data would be truncated.
The statement has been terminated.

伟大的。保留数据完整性,并且调用者知道这一点。现在让我们定义一个存储过程来插入它:

CREATE PROCEDURE spTestTableInsert
    @testStringField [nvarchar](5)
AS
    INSERT INTO testTable(testStringField) VALUES(@testStringField)
GO

并执行它:

EXEC spTestTableInsert @testStringField = N'string which is too long'

没有错误,1 行受到影响。一行被插入到表中,其中testStringField作为“字符串”。 SQL Server 默默地截断了存储过程varchar范围。

现在,这种行为有时可能很方便,但我认为没有办法将其关闭。这非常烦人,因为我want如果我向存储过程传递太长的字符串,就会出错。似乎有两种方法可以解决这个问题。

首先,声明存储过程@testStringField参数大小为 6,并检查其长度是否超过 5。这看起来有点像 hack,并且涉及大量令人恼火的样板代码。

其次,只需将所有存储过程 varchar 参数声明为varchar(max),然后让INSERT存储过程中的语句失败。

后者似乎工作正常,所以我的问题是:使用是一个好主意吗varchar(max)对于 SQL Server 存储过程中的字符串总是如此,如果我真的希望存储过程在传递太长的字符串时失败?这可能是最佳实践吗?无法禁用的静默截断对我来说似乎很愚蠢。


It just is.

但我从未注意到问题,因为我的检查之一是确保我的参数与表列长度匹配。在客户端代码中也是如此。就我个人而言,我希望 SQL 永远不会看到太长的数据。如果我确实看到了截断的数据,那么造成它的原因就会很明显。

如果您确实觉得需要 varchar(max),请注意巨大的性能问题,因为数据类型优先级。 varchar(max) 的优先级高于 varchar(n)(最长的优先级最高)。因此,在这种类型的查询中,您将得到扫描而不是查找,并且每个 varchar(100) 值都会被强制转换为 varchar(max)

UPDATE ...WHERE varchar100column = @varcharmaxvalue

Edit:

有一个打开 Microsoft Connect 项目关于这个问题。

它可能值得包含在Erland Sommarkog 的严格设置 (and 匹配的连接项目).

编辑 2,马丁斯评论后:

DECLARE @sql VARCHAR(MAX), @nsql nVARCHAR(MAX);
SELECT @sql = 'B', @nsql = 'B'; 
SELECT 
   LEN(@sql), 
   LEN(@nsql), 
   DATALENGTH(@sql), 
   DATALENGTH(@nsql)
;

DECLARE @t table(c varchar(8000));
INSERT INTO @t values (replicate('A', 7500));

SELECT LEN(c) from @t;
SELECT 
   LEN(@sql + c), 
   LEN(@nsql + c), 
   DATALENGTH(@sql + c), 
   DATALENGTH(@nsql + c) 
FROM @t;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL Server 静默截断存储过程中的 varchar 的相关文章

随机推荐

  • SVG 中的单击事件坐标

    该 HTML 包含 SVG div class container div class spacer div div
  • 使用 grep 获取每行匹配后的下一个 WORD

    我想得到 GET 来自我的服务器日志的查询 例如 这是服务器日志 1 0 0 127 in addr arpa 10 Jun 2012 15 32 27 code 404 message File not fo 1 0 0 127 in a
  • Emacs:如何绑定敲击两次的键?

    我正在使用 Emacs 23 并且我正在绑定C 功能的组合键 global set key kbd C myfunction 是否可以绑定快速 双击 按键 例如我想调用一个函数myfunction打字时 很快两次 没有任何内置内容 但您可以
  • 在 QtableView 中添加复选框作为垂直标题

    我试图拥有一个 QTableView 复选框 因此我可以使用它们进行行选择 我已经设法做到了这一点 现在我希望标题本身成为复选框 以便我可以选中 取消选中 All 或 any row 我已经找了好几天了 但没能做到 我尝试对模型使用 set
  • wpf - 验证 - 如何显示工具提示并禁用“运行”按钮

    你好 我需要验证应用程序中的一些文本框 我决定使用验证规则 数据错误验证规则 这就是为什么在我的类中我实现了 IDataErrorInfo 接口并编写了适当的函数 在我的 xaml 代码中 我向文本框添加了绑定和验证规则
  • 如何让 docker-compose 始终从新镜像重新创建容器?

    我的 Docker 镜像构建在 Jenkins CI 服务器上 并推送到我们的私有 Docker 注册表 我的目标是使用 docker compose 配置环境 该环境始终启动图像的原始构建状态 我目前在不同的机器上使用 docker co
  • 从文件夹中的所有工作簿中删除 VBA 代码

    我正在尝试构建代码来远程循环包含 xls 文件的文件夹并删除其中包含的宏 到目前为止 我已经使各个组件正常工作 但在激活各种工作簿 然后以编程方式确保每个文件中引用 Microsoft Visual Basic for Applicatio
  • 使用 read() 方法从 Amazon S3 读取大尺寸 JSON 文件时出现内存错误

    我正在尝试使用 Python 将大量 JSON 文件从 Amazon S3 导入到 AWS RDS PostgreSQL 中 但是 这些错误发生了 回溯 最近一次调用最后一次 文件 my code py 第 67 行 位于 file con
  • Eclipse SVN 同步工作区错误 - 更新 SVN 工作区的同步视图 - java/nio/file/Paths

    我今天更新了 Eclipse SVN 插件 之后我无法将我的工作区与 SVN 存储库同步 我使用的是java 1 6 我也尝试过使用java 1 7 我仍然在 Eclipse 中遇到以下错误 期间发生内部错误 更新 SVN 工作区的同步视图
  • 如何在 OS X 上将进程窗口置于前台?

    我有一个简单的 shell python 脚本 可以打开其他窗口 我想在脚本完成后将运行脚本的终端带到前台 我知道我的父窗口的进程ID 如何将给定窗口置于前台 我想我必须一路从 PID 中找出窗口名称 不确定是否有proper方式 但这对我
  • 嵌套 HTML 列表中的不同字体大小

    我创建了一个嵌套的ol li为我的网站列出 CSS 中的类 但由于每个li显示在不同的font size 虽然我已经定义了font size to it number list ol font normal 1 2em Arial Helv
  • 如何设置等高线标签的背景颜色

    我正在使用命令 axins clabel c levls fontsize 4 fmt 4 2f colors white 为了为我的轮廓生成标签 我希望它们是白色的 颜色 白色 有效 和红色背景 我不知道是否可以为它们指定背景颜色 我迟到
  • eclipse c++ 没有什么可构建错误

    所以我尝试构建一个 C 项目 但随后出现此错误 Build of configuration Release for project p Internal Builder is used for build Nothing to build
  • 类型实例化太深并且可能是无限的

    这里如何处理这个错误呢 我可以限制递归深度 或者只是告诉 TS 可以吗 export type StateUnion
  • 检查当前用户是否是活动目录组的成员

    我需要检查当前用户是否是活动目录组的成员 我首先获取当前用户 如下所示 现在我想知道如何检查此 CurrentUser 是否在活动目录组 CustomGroup 中 string CurrentUser WindowsIdentity Ge
  • Flutter/Dart语言的客户端证书认证

    我对证书世界相当陌生 我决定创建一个必须使用证书来访问 API 的应用程序 我创建了自签名 CA 证书 SSL 证书和客户端证书 我将它们导入 Windows Server 并正确配置 IIS 我可以使用 clientcertificate
  • 当字符串为十六进制且前缀为“0x”时,将字符串转换为整数时不一致

    使用 PHP 5 3 5 不确定这在其他版本上如何工作 我对使用包含数字的字符串感到困惑 例如 0x4B0 or 1 2e3 PHP 处理此类字符串的方式对我来说似乎不一致 只有我一个人吗 或者这是一个错误 或者未记录的功能 或者我只是错过
  • Android 嵌套列表视图

    是否可以 建议使用嵌套列表视图 即包含在另一个列表视图的一行中的列表视图 一个例子是我的主列表显示博客文章 然后在每一行中 您都会有另一个列表视图来显示每个帖子的评论 这将是可折叠的 我今天遇到了同样的问题 所以这就是我解决它的方法 我有一
  • 用于聚合/串联的 SQL 查询

    我有一个这样的表 ID Name 1 john 1 molly 2 greg 2 sean 1 holly 2 mill SQL 查询应该是什么来聚合结果 如下所示 ID Name 1 john molly holly 2 greg sea
  • SQL Server 静默截断存储过程中的 varchar

    根据本次论坛讨论 SQL Server 我使用的是 2005 但我收集这也适用于 2000 和 2008 默默地截断任何varchar您将 varchar 的长度指定为存储过程参数 即使直接使用INSERT实际上会导致错误 例如 如果我创建