2015-04-02 62 views
-1

我们有一些在过去一天开始抛出错误的代码。该代码几个月没有改变。该错误消息是:无理由的SQL截断错误

消息8152,级别16,状态2
字符串或二进制数据将被截断。

的SQL语句是:

UPDATE TUP 
SET insured_state_cd = UTCA.state_province_cd 
FROM #TEMP_UAFR_POLICY TUP 
    JOIN dbo.UVW_THIRDS UT ON 
     TUP.prim_owner_third_id = UT.third_id 
    JOIN dbo.UVW_THIRDS_CONTACTS_ADDRESSES UTCA ON 
     UT.primary_address_id = UTCA.address_id 
    JOIN dbo.UVW_INTERNATIONAL_COUNTRY UIC ON 
     UTCA.country_cd = UIC.country_cd 

现在,我会告诉你,是的,UTCA.state_province_cd列比insured_state_cd列大。我们知道这不是一件好事,但我们的测试过程至少需要一个月的时间才能将变更批准并投入生产。我们真的需要弄清楚这个问题的原因。

我们检查了UTCA表,没有记录的长度超过2,这是TUP表中列的大小。由于它是CHAR类型,我们还检查了表的二进制值以确保它不是回车或其他隐藏字符。

为了增加神秘感,此代码的工作:

UPDATE TUP 
SET insured_state_cd = UTCA.state_province_cd 
FROM #TEMP_UAFR_POLICY TUP 
    JOIN dbo.UVW_THIRDS UT ON 
     TUP.prim_owner_third_id = UT.third_id 
    JOIN dbo.UVW_THIRDS_CONTACTS_ADDRESSES UTCA ON 
     UT.primary_address_id = UTCA.address_id 
    JOIN dbo.UVW_INTERNATIONAL_COUNTRY UIC ON 
     UTCA.country_cd = UIC.country_cd 
WHERE UTCA.state_province_cd IN 
      (SELECT DISTINCT UTCA2.state_province_cd 
      FROM dbo.UVW_THIRDS_CONTACTS_ADDRESSES UTCA2) 

正如你所看到的,第二个代码是一样的,第一,它基本上只是检查做1 = 1?此外,代码以原始形式在我们的开发服务器上运行。我们直接备份数据库,恢复到开发,运行代码,它的工作原理。

+0

如果你只想要UTCA.state_province_cd的前两个字符,那'SET insured_state_cd = LEFT(UTCA.state_province_cd,2)...'''开发人员和生产数据库是否运行*完全相同版本的SQL Server? – 2015-04-02 18:28:17

+1

下面是一个*疯狂的想法 - 为什么不创建#temp表,以便其列和数据类型实际上匹配源表?我无法理解为什么增加#temp表定义的长度需要任何时间来批准和部署。如果这需要一个月,那么你有更大的问题,字符串截断。 – 2015-04-02 18:57:10

+1

另外,你是否检查了连接产生的值,或者表中的所有***值? SQL Server可以按照不同的顺序优化事物,其中在一个服务器上的过滤器之前检查长度,并且在另一个过滤器之后检查长度。 – 2015-04-02 18:59:35

回答

1

我的猜测是你用LEN(列)来检查数据?这将告诉你字符的数量,不包括任何空格。我有一种感觉,那就是空白为什么会出错。尝试修剪白色空间。

UPDATE TUP 
SET insured_state_cd = RTRIM(LTRIM(UTCA.state_province_cd)) 
FROM #TEMP_UAFR_POLICY TUP 
    JOIN dbo.UVW_THIRDS UT ON 
     TUP.prim_owner_third_id = UT.third_id 
    JOIN dbo.UVW_THIRDS_CONTACTS_ADDRESSES UTCA ON 
     UT.primary_address_id = UTCA.address_id 
    JOIN dbo.UVW_INTERNATIONAL_COUNTRY UIC ON 
     UTCA.country_cd = UIC.country_c 
+0

当然,它可以通过使不幸的是,由于疯狂的代码更改过程,字段长度匹配或修剪,直到发布后我才能更改。这个过程很好地工作了很多年,并在过去的一天刚刚打破。就模式或设置而言,没有任何变化,显然数据总是在变化,但在我正在使用的时间范围内没有其他变化。 – Kevin 2015-04-02 19:33:18

+0

您是否尝试过SELECT UTCA.state_province_cd FROM UTCA WHERE DATALENGTH(CAST(UTCA.state_province_cd AS VARCHAR(5))> 2?是否返回任何内容? – Stephan 2015-04-02 20:05:06

0

你说什么都没有引发任何红旗或对我有明显的答案。这里有一些我会研究的东西(你可能已经完成了)。

你说“CHAR”类型。 CHAR或VARCHAR?让我们想知道领先和/或尾随空格。 (那里有任何nvarchars?怎么样varchar(max)?)它有助于查看#TEMP_UAFR_POLICY和UVW_THIRDS_CONTACTS_ADDRESSES的表定义。

您已经使用了LEN() DATALENGTH()函数来检查列,是吗?

“支持生产并在开发中恢复”与#tempdbs结合使我想起我们安装了SQL代码页(或其他)与我们其他所有SQL安装不同的。数据库都是一样的,但系统数据库(最值得注意的是tempdb)是在不同的假设下运行的,并且导致了一些相当微妙的问题。也许有什么事情在那里?

在两种环境之间检查并比较SQL的服务包的版本和版本。

+0

好主意,但不幸的是我在这里没有找到任何东西。 2)和char(5),由于它们是CHAR,它们总是返回一个datalength =字段的长度,我检查了tempdb,它具有相同的设置,包括两台服务器上的排序规则。 – Kevin 2015-04-02 19:30:58