Sql выбрать вставку отладки - PullRequest
0 голосов
/ 03 августа 2011

Я хотел бы найти быстрый способ отладки оператора вставки-выбора.Пример:

Create table tbl_int (
        tabid int identity,
        col1 bigint)

Create table tbl_char(
        tabid int identity,
        col2 nvarchar(255))


insert into tbl_char(col2) 
    select '1' union 
    select '2' union
    select 'a'

insert into tbl_int(col1)
    select col2 
    from tbl_char

Конечно, выбранная вставка не запускается, и очевидно, что «a» нельзя преобразовать в bigint.Но что происходит, когда у меня есть 1 миллион записей в tbl_char.Есть ли способ найти исходное значение ошибки: «Ошибка преобразования типа данных nvarchar в bigint».Ps Использование функции convert или cast и сканирование таблицы с помощью top до нахождения правильного значения немного дороже.

Ответы [ 3 ]

2 голосов
/ 03 августа 2011

Почему бы вам не обернуть SQL, который выбрасывает исключение, в блок Try / Catch, чтобы получить больше информации об этом

BEGIN TRY
    SELECT *
        FROM sys.messages
        WHERE message_id = 21;
END TRY
GO
-- The previous GO breaks the script into two batches,
-- generating syntax errors. The script runs if this GO
-- is removed.
BEGIN CATCH
    SELECT ERROR_NUMBER() AS ErrorNumber;
END CATCH;
GO

ниже приведены все сведения об ошибках, которые вы можете проверить

ERROR_NUMBER() returns the error number.

ERROR_MESSAGE() returns the complete text of the error message. The text includes the values supplied for any substitutable parameters such as lengths, object names, or times.

ERROR_SEVERITY() returns the error severity.

ERROR_STATE() returns the error state number.

ERROR_LINE() returns the line number inside the routine that caused the error.

ERROR_PROCEDURE() returns the name of the stored procedure or trigger where the error occurred.

http://msdn.microsoft.com/en-us/library/ms179296.aspx

если этого недостаточно, вы даже можете написать запрос, чтобы выбрать все записи, в которых определенное поле не может быть преобразовано в число (в вашем случае есть NVarChar, который не конвертируется)

В следующем примере ISNUMERIC используется для возврата всех почтовых индексов, которые не являются числовыми значениями.

SELECT City, PostalCode
FROM Person.Address 
WHERE ISNUMERIC(PostalCode)<> 1

http://msdn.microsoft.com/en-us/library/ms186272.aspx

0 голосов
/ 03 августа 2011

Давайте начнем с того, почему вы пытаетесь отправить данные, которые не совпадают с типом данных, в другую таблицу? Если вы не хотите, чтобы в столбце были не целочисленные данные, почему вы позволяете им быть строковыми данными для начала? Итак, сначала вам нужно выяснить, есть ли у вас проблема дизайна, которая влияет на целостность данных.

Если вы выполняете импорт из какой-либо другой системы и не можете контролировать тип данных, который вы используете, вам необходимо очистить данные перед выполнением вставки. Для этого не существует единого размера. Вам нужно будет написать код, чтобы найти все данные, которые не будут соответствовать условиям таблицы, в которую вы перемещаете данные по типу данных и поле за полем. Это может быть намного сложнее, чем использование isnumeric (которое может иметь ложные срабатывания, особенно если там также есть десятичная информация) и isdate (), и вам может потребоваться написать функции, соответствующие вашим потребностям. Для правильной очистки может потребоваться много времени. Вам может потребоваться ограничить значения определенным подмножеством или иметь таблицу преобразования, которая преобразует то, что они помещают в таблицу, в то, что примет ваша система. Предложите сначала определить неверные данные, переместить их в таблицу исключений, а затем выполнить вставку на основе записей, которых нет в таблице исключений.

0 голосов
/ 03 августа 2011

Как вы понимаете, значение char преобразуется в bigint при выполнении команды insert..select. Таким образом, мы не можем избежать преобразования, но мы можем попытаться избежать сканирования второй таблицы. Предлагаю создать INSTEAD OF INSERT триггер для таблицы tbl_int. В теле этого триггера вы можете преобразовать значение char в bigint, а если получите ошибку, вы можете вставить это значение char в промежуточную таблицу. Если при преобразовании ошибки нет, вы можете вставить это значение bigint в таблицу tbl_int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...