我正在C#应用程序中为MySQL创建存储过程。 该存储过程包含一些动态创建的SQL,用于删除索引(如果存在),然后[重新]创建它。 SQL代码在MySQL Workbench中可以正常工作,但是当我从C#应用程序运行它时,却遇到了MySQL异常。 这是存储过程代码(正如我在C#中所使用 ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
我有问题,我无法使用存储过程查看用户信息。 该过程接受三个参数: table
, column
和searchBySomething
。 每次我想使用其他列搜索用户时,column变量都会接收ID的列,而searchBySomething
变量会接收特定的id,该过程是可行的,但是当我发送另一列时,我会收到错误消息
无效的列名(数据)
该过程如下所示:
ALTER PROCEDURE [dbo].[userDetailsDisplay]
@table NVARCHAR(30),
@column NVARCHAR(30),
@searchBySomething NVARCHAR(30)
DECLARE @sql NVARCHAR(100)
SET @sql = 'SELECT * FROM ' + @table + ' WHERE ' + @column + ' = ' + @searchBySomething
EXECUTE sp_executesql @sql
因此,您得到的特定错误是因为您没有检查输入以查看传递给@column
的字符串是否确实存在。 您可以根据元数据目录视图sys.columns
进行以下检查:
if not exists
(
select 1
from sys.columns
where object_id = object_id(@table)
and name = @column
)
begin
raiserror('Column %s does not exist in table %t', 16, 1, @column, @table)
return
end
但是,如果我不指出两件事,我将被忽略。
首先,这种动态表动态where子句模式是非常不好的做法。 如果是针对已经具有数据库访问权限的人员,则他们只需查询自己的表即可。 而且,如果是针对外部用户的,那么您基本上可以通过此过程为他们提供完整的数据库读取访问权限。 当然,在极少数情况下需要使用此模式,因此,如果您对使用动态sql设置得一无所知,那将引出我的下一个观点。
您编写的代码容易受到SQL注入攻击。 任何时候使用动态SQL时,都必须非常小心其构造方式。 说我输入了列名; drop database [admin]--
; drop database [admin]--
假设您有这样一个数据库,我可能会很乐意被执行,而您的数据库也会消失。
如何确保动态SQL的安全是一个复杂的话题,但是如果您想认真学习它,那可能是您可以找到的最好的文章之一。 http://www.sommarskog.se/dynamic_sql.html
通过参数化查询并在表和列上使用quotename()
,我将其修改为如下所示。 如果有人尝试进行注入攻击,这仍然会引发奇怪的错误,但是至少它不会实际执行他们的代码。
create procedure [dbo].[userDetailsDisplay]
@table nvarchar(30),
@column nvarchar(30),
@searchBySomething nvarchar(30)
as
begin
declare
@sql nvarchar(max),
@params nvarchar(1000)
if not exists
(
select 1
from sys.columns
where object_id = object_id(@table)
and name = @column
)
begin
raiserror('Column %s does not exist in table %t', 16, 1, @column, @table)
return
end
select @sql = '
select *
from ' + quotename(@table) + ' WHERE ' + quotename(@column) + ' = @searchBySomething'
execute sp_executesql
@stmt = @sql,
@params = '@searchBySomething nvarchar(30)',
@searchBySomething = @searchBySomething
end
只需检查以确保表中存在该列。
每个@table
调用,检查@column
变量是在该表中。
SET @sql = 'SELECT * FROM ' + @table + ' WHERE ' + @column + ' = ' +''' @searchBySomething +''''
例如: select * from table where column ='value'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.