寻找一种与同一台服务器上不同表中的数据进行交互的方法,我遇到了this question上提供的解决方案。据我所能找到的,没有其他方法可以将表名“传递”给查询。问题在于它似乎容易受到SQL注入的攻击;例如,我可以使用此代码将某人添加到名为“ School1”的数据库的“学生”表中:
CREATE PROCEDURE AddStudent (
@DBName char(10),
@FirstName char(30),
@LastName char(30)
) AS
DECLARE @SqlScript varchar(MAX) = '
INSERT INTO ' + @DBName + '.dbo.student (FirstName, LastName) VALUES (' +
@FirstName + ', ' + @LastName + ');'
EXECUTE (@SqlScript)
当我将存储过程称为“ AddStudent”时,我只需传递变量“ School1”,“ Bobby”和“ Tables”。您可能会看到前进的方向...
即使数据库名称以某种方式(因此安全)以编程方式确定了客户端,little Bobby Tables could choose to use his full name并使用@FirstName
= Robert ,@LastName
= '); DROP TABLE学生;- 导致我们各种各样的问题。
当然,这可能是一个不太可能且极端的示例,但是您可以理解。有什么办法可以防止这种情况?
答案 0 :(得分:0)
Dale提到每个数据库都必须有一个独立的存储过程,这给了我将其分为两个独立的想法。一个仅计算出要使用的数据库,然后将值传递给另一个数据库,该数据库实际上添加了学生记录。它并不是特别优雅,但是它可以让您在SQL中完成很多工作:
首先,完全按照您的期望添加学生的查询-将其放入每个数据库中:
CREATE Procedure [dbo].[AddStudent] (@FirstName char(10), @LastName char(10)) AS
INSERT INTO SCHOOL1.dbo.Student (FirstName, LastName) VALUES
(@FirstName, @LastName);
然后是另一个数据库,该数据库可以存在于master数据库中,也可以存在于每个数据库中,具体取决于将其发送到哪个数据库最方便:
CREATE Procedure [dbo].[AddStudentUniversal] (@DbName char(10), @FirstName char(10), @LastName char(10)) AS
IF (@DbName = 'SCHOOL1') EXECUTE SCHOOL1.dbo.AddStudent @FirstName, @LastName
IF (@DbName = 'SCHOOL2') EXECUTE SCHOOL2.dbo.AddStudent @FirstName, @LastName