2015-04-02 2 views
-1

У нас есть код, который запустил ошибку за последний день. Код не менялся в течение нескольких месяцев. Сообщение об ошибке:Ошибка обрыва SQL без причины

Msg 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? Кроме того, код работает на нашем сервере разработки, как есть, в оригинальной форме. Мы буквально поддерживали db, восстанавливали Dev, запускали код, и он работает.

+0

Если вам нужны только первые два символа из UTCA.state_province_cd, как насчет 'SET insured_state_cd = LEFT (UTCA.state_province_cd, 2) ...'? И есть ли dev и производственные БД, работающие с * точной * той же версией SQL Server? –

+1

Вот идея * сумасшедшая * - почему бы не создать таблицу #temp, чтобы ее столбцы и типы данных действительно соответствовали исходным таблицам? Я не могу понять, почему увеличение длины определения таблицы #temp может потребоваться в любое время для утверждения и развертывания.Если это занимает месяц, тогда у вас больше проблем, связанных с усечением строк. –

+1

Также вы проверили значения, полученные в результате объединения, или *** все значения *** в таблице? SQL Server может оптимизировать вещи в разных заказах, где длина проверяется * до * фильтра на одном сервере, а длина проверяется * после * фильтра на другом. –

ответ

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

+0

Вы пробовали SELECT UTCA.state_province_cd FROM UTCA WHERE DATALENGTH (CAST (UTCA.state_province_cd AS VARCHAR (5))> 2? Он что-то возвращает? – Stephan

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, и он имеет те же настройки, включая сортировку на обоих серверах. Оба они равны уровню sp и patch. – Kevin