use*_*054 1 sql-server stored-procedures dynamic-sql t-sql
我一般是 SQL 新手,所以我在设计的一些存储过程中遇到了一些问题。我的程序接受 3 个参数。位置(或表名基本上是 varchar)、房间号 (varchar) 和 'xxx-xxxx' 形式的电话号码 (char)。这是该过程的代码。
ALTER PROCEDURE [dbo].[AddPhoneNumberToRoom]
@Location varchar(25),
@Room varchar(10),
@PhoneNumber char(8)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @String varchar(100);
SELECT @String = ' UPDATE ' + @Location +
' SET PhoneNumber = ' + @PhoneNumber +
' WHERE Room = ' + @Room;
EXEC(@String);
END
Run Code Online (Sandbox Code Playgroud)
我收到的错误是:
UPDATE 语句与 FOREIGN KEY 约束“FK_Apartments_PhoneNumbers”冲突。冲突发生在数据库“CMPhone”、表“dbo.PhoneNumbers”、列“PhoneNumber”中。
电话号码在 PhoneNumber 表中,所以当我这样做时:
UPDATE Apartments SET PhoneNumber='123-4567' WHERE Room='2'
Run Code Online (Sandbox Code Playgroud)
它工作得很好。该PhoneNumbers
表还看起来是这样的,只是在它的一个数字。
PhoneNumber
-----------
123-4567
Run Code Online (Sandbox Code Playgroud)
PRINT @String;
将产生它所说的PhoneNumber = 123-4567
(它把它当作一个表达式,123
减去4567
,它等于-4444
),而不是PhoneNumber = '123-4567'
像你硬编码的例子。所以你应该用两个单引号来转义你附加的值:
SELECT @String = ' UPDATE ' + @Location +
' SET PhoneNumber = ''' + @PhoneNumber + '''
WHERE Room = ''' + @Room + ''';';
Run Code Online (Sandbox Code Playgroud)
但更好的是,为了更好地保护自己免受 SQL 注入(请参阅此处、此处和此处),您应该 (a) 检查该@Location
表是否有效,(b)QUOTENAME()
无论如何,以及 (c) 传入其他两个值作为正确键入的参数,而不是将它们附加到字符串:
IF OBJECT_ID(N'dbo.' + @Location) IS NOT NULL
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'UPDATE dbo.' + QUOTENAME(@Location)
+ N' SET PhoneNumber = @PhoneNumber
WHERE Room = @Room;';
EXEC sys.sp_executesql @sql,
N'@PhoneNumber CHAR(8), @Room VARCHAR(10)',
@PhoneNumber, @Room;
END
Run Code Online (Sandbox Code Playgroud)
更妙的是,您不应该为每个Location
恕我直言有一个单独的表- 位置应该是一列。那么您根本不需要动态 SQL。
归档时间: |
|
查看次数: |
79 次 |
最近记录: |