我一直在寻找输入变量表名的方法,似乎最好的方法是使用动态sql,尽管它可能导致SQL注入(inject)。谁能演示一下这是如何在 C# 中完成的?例如,我想要一些东西来实现这样的东西:
SqlCommand command= new SqlCommand("SELECT x FROM @table WHERE @column = @y", conn);
从这里可以看出,表名和列名都是变量。我之前使用过字符串连接,但出于安全目的我想避免这样做。不确定这是否重要,但是表和列不是由用户输入确定的,而是实际上由用户选择的链接确定的,所以也许 SQL 注入(inject)在这里不是问题?
最佳答案
我能想到的最好的方法是两部分。
您有一个将名称作为参数的存储过程。此过程首先在目录中查找表名称 (
Information_Schema.Table
),并获取正确的名称以验证其是否有效。然后使用此查找存储过程构造所需的 SQL,而不是根据参数。
使用此查找实际上可以防止传入无效的表名称。
CREATE PROCEDURE RunSQL
(@table NVARCHAR(50))
AS
BEGIN
DECLARE @validTableName NVARCHAR(50)
SELECT
@validTableName = TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_NAME = @table
AND SCHEMA_NAME = 'dbo' -- here you can limit or customise the schema
IF @validTableName IS NULL
RAISE ... raise an exception
DECLARE @dynamicSql NVARCHAR(100) = REPLACE('SELECT * FROM dbo.[#TABLE#]', '#TABLE' @validTableName)
EXECUTE sp_executesql .... @dynamicSql ....
END
您可以使用扩展它来验证、架构、列等...
您最终需要构建自己的 SQL 并防止注入(inject)。这是无法回避的。
关于c# - C# 中使用动态 SQL 的变量表名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14026823/