Сообщение об ошибке T-SQL 207 При динамической передаче значений - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь создать хранимую процедуру, которая позволяет передавать ей значения, однако при попытке использовать Dynamic T-SQL возникает ошибка MSG 207

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

https://www.tsql.info/error/msg-207-level-16-invalid-column-name.php

Это, однако, не имеет смысла, так как следующее жестко закодированное утверждение прекрасно работает.

INSERT INTO [dbo].[tDriversLicense] (DriversLicensePrefix,    DriversLicenseSuffix, DateAdded, DriversLicenseNumber)
    VALUES ('shockc', '11653798', GETDATE(), 'GAD4859');

ALTER PROCEDURE [dbo].[spAddDriversLicense]
    -- Add the parameters for the stored procedure here
    @DriversLicensePrefix NCHAR(8),
    @DriversLicenseSuffix NCHAR(10)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

            DECLARE @sqlInsertDriversLicense NVARCHAR(MAX)
            SET @sqlInsertDriversLicense = 'INSERT INTO [dbo].[tDriversLicense] (DriversLicensePrefix, DriversLicenseSuffix, DateAdded, DriversLicenseNumber)
                VALUES (' + @DriversLicensePrefix + ', ' + @DriversLicenseSuffix + ', GETDATE(), GPC4859);'

            EXECUTE sp_executesql @sqlInsertDriversLicense

END

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

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

https://www.youtube.com/watch?v=RHHKG65WEoU

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Как уже отмечалось в комментарии, такой динамический подход вообще не нужен.

Следующий код покажет прямой и динамичный подход. Попробуйте:

USE master;
GO
CREATE DATABASE testDB;
GO
USE testDB;
GO
CREATE TABLE TestTable(SomeContent VARCHAR(100),SomeDate DATETIME,SomeFixString VARCHAR(100));
GO

- эта процедура будет использовать параметры напрямую. Нет необходимости в каком-либо динамическом SQL:

CREATE PROCEDURE TestStraight(@content VARCHAR(100))
AS
BEGIN
    INSERT INTO TestTable(SomeContent,SomeDate,SomeFixString)
    VALUES(@content,GETDATE(),'Proc Straight');
END
GO

- эта процедура будет использовать реальных параметров . Вы не должны никогда использовать параметры в конкатенации строк . Однажды вы могли бы встретиться Бобби таблицы ...

CREATE PROCEDURE TestDynamic(@content VARCHAR(100))
AS
BEGIN
    DECLARE @cmd NVARCHAR(MAX)=
    N'INSERT INTO TestTable(SomeContent,SomeDate,SomeFixString)
      VALUES(@DynamicContent,GETDATE(),''Proc Dynamic'');'
    EXEC sp_executesql @cmd,N'@DynamicContent VARCHAR(100)',@DynamicContent=@content;
END
GO

- Проверьте это

EXEC TestStraight 'yeah!';
EXEC TestDynamic 'oh yeah!';
SELECT * FROM TestTable;
GO

- Очистить

USE master;
GO
--careful with real data!
--DROP DATABASE testDB;
0 голосов
/ 09 ноября 2018

При работе с динамическими строками сначала выберите их, чтобы вы могли проверить работоспособность полученного синтаксиса.

Вам нужны одинарные кавычки в результате, поэтому вам нужно больше, чем одиночные кавычки, в коде:

declare @DriversLicensePrefix nchar(8) = 'A2345678'
declare @DriversLicenseSuffix nchar(10) = 'abcdefghij'

DECLARE @sqlInsertDriversLicense nvarchar(max)
SET @sqlInsertDriversLicense = 'INSERT INTO [dbo].[tDriversLicense] (DriversLicensePrefix, DriversLicenseSuffix, DateAdded, DriversLicenseNumber)
                VALUES (N''' + @DriversLicensePrefix + ''', N''' + @DriversLicenseSuffix + ''', ''' + convert(char(8),GETDATE(),112) + ''', ''GPC4859'');'

select @sqlInsertDriversLicense

+-------------------------------------------------------------------------------------------------------------------+
|                                                      result:                                                      |
+-------------------------------------------------------------------------------------------------------------------+
| INSERT INTO [dbo].[tDriversLicense] (DriversLicensePrefix, DriversLicenseSuffix, DateAdded, DriversLicenseNumber) |
| VALUES (N'A2345678', N'abcdefghij', '20181109', 'GPC4859');                                                         |
+-------------------------------------------------------------------------------------------------------------------+

NB Вы должны использовать convert(char(8),getdate(),112) SQL Server распознает формат ГГГГММДД в ​​качестве значения даты независимо от настроек сервера по умолчанию.


Результат, приведенный выше, демонстрирует, какой оператор вставки ДОЛЖЕН быть, обратите внимание, что он содержит несколько одинарных кавычек.

Когда вы объединяете оператор SQL, вы также имеете дело со строками, и каждая их часть должна быть заключена в одинарные кавычки.

Таким образом, для одинарных кавычек существует множество потребностей.

А; Таким образом, вам нужно несколько одинарных кавычек на протяжении всей конкатенации, некоторые из которых помогут сформировать оператор SQL, а другие - ВНУТРИ этого оператора.

/* get this into @sql */
select 'Y' as col1;

declare @SQL as nvarchar(max)

set @SQL = N'select ''Y'' as col1;'

select @SQL;

+---------------------+
|        @SQL         |
+---------------------+
| select 'Y' as col1; |
+---------------------+

В большем запросе 2 переменные определены как NCHAR (8) или (10), так как вы определили их как N char, тогда при вставке данных в них вы должны префиксировать этот ввод как N

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