数据库名称作为变量 -Dynamic SQL inside stored procedure
Database Name as Variable -Dynamic SQL inside stored procedure
我很难解决这个问题。我的项目要求需要能够使用数据库名称作为参数。我认为这很容易,因为在存储过程中,我们可以像 [dbname].[dbo].tblname
一样使用它。但是当我用变量替换 dbname 时,它不起作用。
所以经过一段时间谷歌搜索后,我决定在存储过程中使用动态 SQL。但是,目前我很难调试这部分。在我的程序中,它引发语法错误。我希望有人能给我一个提示,或者对我的项目有更好的想法。提前致谢!
SELECT @DBName=DBName FROM Client WHERE ClientCode = @ClientCode
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' + @DBName +
N'.[dbo].Users AS A INNER JOIN'+ @DBName +
N'.[dbo].UserRoles AS B On B.RoleCode = A.UserRole INNER JOIN ' + @DBName +
N'.[dbo].Branch AS C On C.BranchCode = A.BranchCode WHERE Username= ' + @UserName +
N' AND Password = ' + @Password
Declare @ParamDefinition AS NVarchar(2000)
Set @ParamDefinition = N' @ClientCode VARCHAR(20),' +
N' @UserName Varchar(15),' +
N' @Password NVARCHAR(200)'
exec sp_executesql @SQL,@ParamDefinition
我这样重写,这样更容易阅读
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' +
@DBName + N'.[dbo].Users AS A INNER JOIN ' +
^^^ space add here
@DBName + N'.[dbo].UserRoles AS B On B.RoleCode = A.UserRole INNER JOIN ' +
@DBName + N'.[dbo].Branch AS C On C.BranchCode = A.BranchCode ' +
N' WHERE Username= ' + @UserName +
N' AND Password = ' + @Password
就像 Joe R 说的那样,缺少一个 space。
您在动态 SQL 生成的第二行缺少 space。
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' + @DBName +
N'.[dbo].Users AS A INNER JOIN ' + @DBName + -- space added
N'.[dbo].UserRoles AS B On B.RoleCode = A.UserRole INNER JOIN ' + @DBName +
N'.[dbo].Branch AS C On C.BranchCode = A.BranchCode WHERE Username= ' + @UserName +
N' AND Password = ' + @Password
- 在动态 SQL 中使用 QUOTENAME,这对于防止 SQL 注入
非常重要
- 用户名和密码可以并且应该保留参数
- 传入声明的参数
像这样:
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' + QUOTENAME(@DBName) +
N'.[dbo].Users AS A INNER JOIN '+ QUOTENAME(@DBName) +
N'.[dbo].UserRoles AS B On B.RoleCode = A.UserRole INNER JOIN ' + QUOTENAME(@DBName) +
N'.[dbo].Branch AS C On C.BranchCode = A.BranchCode WHERE Username= @UserName AND Password = @Password'
exec sp_executesql @SQL, N'@UserName VARCHAR(15), @Password NVARCHAR(200)', @UserName, @Password
最后:永远不要在数据库中存储密码。请改用 salted hash.
我很难解决这个问题。我的项目要求需要能够使用数据库名称作为参数。我认为这很容易,因为在存储过程中,我们可以像 [dbname].[dbo].tblname
一样使用它。但是当我用变量替换 dbname 时,它不起作用。
所以经过一段时间谷歌搜索后,我决定在存储过程中使用动态 SQL。但是,目前我很难调试这部分。在我的程序中,它引发语法错误。我希望有人能给我一个提示,或者对我的项目有更好的想法。提前致谢!
SELECT @DBName=DBName FROM Client WHERE ClientCode = @ClientCode
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' + @DBName +
N'.[dbo].Users AS A INNER JOIN'+ @DBName +
N'.[dbo].UserRoles AS B On B.RoleCode = A.UserRole INNER JOIN ' + @DBName +
N'.[dbo].Branch AS C On C.BranchCode = A.BranchCode WHERE Username= ' + @UserName +
N' AND Password = ' + @Password
Declare @ParamDefinition AS NVarchar(2000)
Set @ParamDefinition = N' @ClientCode VARCHAR(20),' +
N' @UserName Varchar(15),' +
N' @Password NVARCHAR(200)'
exec sp_executesql @SQL,@ParamDefinition
我这样重写,这样更容易阅读
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' +
@DBName + N'.[dbo].Users AS A INNER JOIN ' +
^^^ space add here
@DBName + N'.[dbo].UserRoles AS B On B.RoleCode = A.UserRole INNER JOIN ' +
@DBName + N'.[dbo].Branch AS C On C.BranchCode = A.BranchCode ' +
N' WHERE Username= ' + @UserName +
N' AND Password = ' + @Password
就像 Joe R 说的那样,缺少一个 space。
您在动态 SQL 生成的第二行缺少 space。
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' + @DBName +
N'.[dbo].Users AS A INNER JOIN ' + @DBName + -- space added
N'.[dbo].UserRoles AS B On B.RoleCode = A.UserRole INNER JOIN ' + @DBName +
N'.[dbo].Branch AS C On C.BranchCode = A.BranchCode WHERE Username= ' + @UserName +
N' AND Password = ' + @Password
- 在动态 SQL 中使用 QUOTENAME,这对于防止 SQL 注入 非常重要
- 用户名和密码可以并且应该保留参数
- 传入声明的参数
像这样:
DECLARE @SQL NVARCHAR(MAX) = N'SELECT * FROM ' + QUOTENAME(@DBName) +
N'.[dbo].Users AS A INNER JOIN '+ QUOTENAME(@DBName) +
N'.[dbo].UserRoles AS B On B.RoleCode = A.UserRole INNER JOIN ' + QUOTENAME(@DBName) +
N'.[dbo].Branch AS C On C.BranchCode = A.BranchCode WHERE Username= @UserName AND Password = @Password'
exec sp_executesql @SQL, N'@UserName VARCHAR(15), @Password NVARCHAR(200)', @UserName, @Password
最后:永远不要在数据库中存储密码。请改用 salted hash.