Ошибка преобразования типа данных в процедуре выполнения - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь запустить процедуру Execute, которая вставит данные в «Таблицу A». Для одного конкретного параметра я установил тип параметра «Date», чтобы соответствовать типу данных столбца «DateExample» в «Table A». По какой-то причине система распознает тип данных поля в источнике данных представления «ViewExample» как nvarchar, даже если тип данных - дата.

Я попытался установить параметр в nvarchar, но я получил ошибку ниже:

Msg 241, Level 16, State 1, Procedure p_example, Line 34 [Batch Start Line 0]
Conversion failed when converting date and/or time from character string

Код:

ALTER Procedure [dbo].[p_example]
,   @DateExample date

AS 

begin

INSERT INTO [DatabaseEx].[dbo].[Table A]
           ([DateExample]

)

values (

    @DateExample


)

end

Select DISTINCT 
    D.DateExample
From DatabaseEx.dbo.ViewExample D

Where 1 = 1

GO



EXECUTE [dbo].[p_example]

    @DateExample = DateExample



GO

Ожидаемые результаты: данные будут вставлены в таблицу без ошибок

Текущие результаты:

Msg 8114, Level 16, State 1, Procedure p_example, Line 0 [Batch Start Line 0]
Error converting data type nvarchar to date.

Ответы [ 2 ]

1 голос
/ 21 июня 2019

TL; DR в конце ответа.

Ниже приводится полный ответ и обоснование моих изменений и предлагаемый подход.

1.Долгий путь вокруг:

Есть несколько настроек и комментариев, которые я бы сделал в отношении вашего кода:

Согласно приведенному ниже определению, ваша хранимая процедура должна получить single значение типа date в качестве параметра (пока все хорошо)

ALTER Procedure [dbo].[p_example]
    @DateExample date
AS 
begin

Ваш запрос вставки принимает параметр @DateExample и добавляет его в [Table A], пока что все хорошо

INSERT INTO [DatabaseEx].[dbo].[Table A]
           ([DateExample])
values (@DateExample)

end

Похоже, это та часть, где вы решаете, какие значения передать в хранимую процедуру.Это место, где я идентифицирую первую возможную проблему.

Select DISTINCT 
    D.DateExample
From DatabaseEx.dbo.ViewExample D
Where 1 = 1

Ваш запрос SELECT DISTINCT не "определяет" значение, хранящееся в "DateExample" , которое вы можете позже передатьхранимая процедура.Чтобы сохранить это значение в месте, где вы можете использовать его повторно, вам нужно сохранить его в переменной (как минимум).

Итак, я бы изменил приведенный выше запрос на:

DECLARE @DateExample date;

Select DISTINCT 
    @DateExample = D.DateExample
From DatabaseEx.dbo.ViewExample D
Where 1 = 1

Однако это еще не все.Приведенный выше запрос все равно не будет выполнен , если SELECT DISTINCT вернет более 1 значения.

SELECT DISTINCT не означает, что вернет одно уникальное значение , однако он вернетвсе уникальные значения хранятся в столбце DateExample из представления DatabaseEx.dbo.ViewExample .

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

DECLARE @DateExampleTable TABLE (dateExample date);

INSERT INTO @DateExampleTable (dateExample)
Select DISTINCT 
    D.DateExample
From DatabaseEx.dbo.ViewExample D
Where 1 = 1

Это будет охватывать все, и выне получит никаких ошибок, если ваш SELECT DISTINCT вернет более 1 строки.

Теперь вы, вероятно, заметили, что имя и тип переменной изменились с DATE на TABLE.Это требует, чтобы мы также изменили код нашей хранимой процедуры, чтобы она принимала этот новый тип параметра.

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

CREATE TYPE DateTableType AS TABLE (DateExample date);

ALTER Procedure [dbo].[p_example]
    @DateExampleParam DateTableType READONLY
AS 
begin

INSERT INTO [DatabaseEx].[dbo].[Table A]
           ([DateExample])
SELECT DateExample
FROM @DateExampleParam 

end

Теперь, когда у нас есть новая версия хранимой процедуры,

EXECUTE [dbo].[p_example]
    @DateExampleParam = @DateTableExample

2.TL; DR Резюме ниже:

Теперь, если бы мы суммировали все, что я только что написал, в один рефакторированный скрипт, это выглядело бы так:

CREATE TYPE DateTableType AS TABLE (DateExample date);
GO    

ALTER Procedure [dbo].[p_example]
    @DateExampleParam DateTableType READONLY
AS 
begin

INSERT INTO [DatabaseEx].[dbo].[Table A]
           ([DateExample])
SELECT DateExample
FROM @DateExampleParam 

end
GO

DECLARE @DateExampleTable TABLE (dateExample date);

INSERT INTO @DateExampleTable (dateExample)
Select DISTINCT 
    D.DateExample
From DatabaseEx.dbo.ViewExample D
Where 1 = 1

EXECUTE [dbo].[p_example]
    @DateExampleParam = @DateExampleTable 
0 голосов
/ 21 июня 2019

Эта строка может привести к полученной вами ошибке:

EXECUTE [dbo].[p_example]

    @DateExample = DateExample

Параметр DateExample ожидает тип данных date, и вы пытаетесь установить для него «DateExample».

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