Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 动态SQL遇到的问题_Sql Server_Tsql_Dynamic Sql - Fatal编程技术网

Sql server 动态SQL遇到的问题

Sql server 动态SQL遇到的问题,sql-server,tsql,dynamic-sql,Sql Server,Tsql,Dynamic Sql,这是执行存储过程的代码: ALTER PROCEDURE [dbo].[Create_Subjects] @Subj_ID nvarchar(9) AS DECLARE @First3Digits nvarchar(3); DECLARE @Result int; DECLARE @Sql nvarchar(max) -- Fetching the fiest 3 digits of the subject SET @First3Digits =

这是执行存储过程的代码:

ALTER PROCEDURE [dbo].[Create_Subjects]
    @Subj_ID nvarchar(9)
AS
    DECLARE @First3Digits nvarchar(3);
    DECLARE @Result int;
    DECLARE @Sql nvarchar(max)

    -- Fetching the fiest 3 digits of the subject
    SET @First3Digits = SUBSTRING(@Subj_ID,1,3);

    -- Check if view is present or not
    IF EXISTS (SELECT 1 FROM sys.views WHERE Name = @First3Digits)
    BEGIN
        SET @Sql = 'select @Result = case when exists (select 1 from dbo.' + quotename(@First3Digits) + ' where SubjectName = ''' + @Subj_ID + ''') then 1 else 0 end';
        EXECUTE sp_executesql @Sql, N'@Subj_ID nvarchar(9), @Result bit out', @Subj_ID = @Subj_ID, @Result = @Result out; 
        -- checking if the subject is present in the view    
    END
    ELSE
    BEGIN
        -- Create a view as view doesn't exist
        SET @Sql = 'create view ' + @First3Digits 
                    + ' as 
    (select SubjectName from dbo.Subjects where SubjectName like '+@First3Digits+'%'+');';
        EXECUTE sp_executesql @Sql, N'@First3Digits nvarchar(3)', @First3Digits= @First3Digits;
        SET @Result = 0;
    END

    RETURN @Result
GO
遇到错误:


味精156,第15级,状态1,第28行
关键字“view”附近的语法不正确

味精102,第15级,状态1,第29行
“')附近的语法不正确


您的SQL存在许多问题。但是首先调试它们的方法是打印SQL而不执行它,然后是普通的SQL,您可以很容易地确定它的错误

  • 构成视图的SQL周围不允许有括号
  • 您必须按照正常方式引用字符串,这意味着将动态字符串中的引号加倍
  • 按照注释中的建议再次使用
    quotename
  • 无需将参数
    @First3Digits
    传递到
    sp_executesql
    中,因为此时您已经使用了它的值-如果您正在创建视图,则必须这样做

  • 注意:正如我在前面的问题中提到的,根据提供的信息,这似乎是一个非常糟糕的设计。几乎可以肯定的是,有一种更好的方法可以解决你的大问题。正如Martin Smith所评论的,an可能值得研究。

    这是create view语句MSG 156的语法,级别15,状态1,第28行关键字“view”附近的语法不正确。Msg 102,级别15,状态1,第29行“%”附近的语法不正确。如果视图名称不符合常规标识符命名规则(例如,它以数字开头),则还必须将名称括在双引号或方括号中。使用
    QUOTENAME
    就像您之前在程序中所做的那样:
    SET@Sql='create view'+QUOTENAME(@First3Digits)
    在创建视图中添加@First3Digits时,您也会丢失撇号。在选择块中,您做的正确,但不是创建视图块。而不是为每个参数创建视图,而是查看内联表值函数。攻击SQL向量是一个SQL注入攻击向量。如果创建视图,这可能是一个固有的问题,但意识到这一点仍然至关重要。@MarcGravel您将如何解决它?无法创建使用参数的视图。。。“所以我想它需要某种方式逃走吗?”戴瑞克我稍微修改了一下我的话;因为涉及到一个视图(第二次阅读),所以问题更大。我可能会用一根非常大的驳船杆来避免这种情况。就像“社交距离”,但对于关系数据库管理系统。是的,我在OP的第一个问题上加了注释。但没有收到任何进一步的详细信息,因此无法提出替代方案。另外,您是否确认您可以在
    nvarchar(3)
    中安装足够的SQL以进行注入攻击?:)
    EXEC [dbo].[Create_Subjects] '1234567890'
    
        set @Sql = 'create view dbo.' + quotename(@First3Digits)
            + ' as'
            + ' select SubjectName'
            + ' from dbo.Subjects'
            + ' where SubjectName like ''' + @First3Digits + ''' + ''%'';';
    
        -- This is how you debug dynamic SQL
        print(@Sql);
    
        execute sp_executesql @Sql;