Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.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
C# SQL脚本数据中的关键字在以编程方式执行时导致问题-C_C#_Sql_Sql Injection_Sqlcommand_Sql Insert - Fatal编程技术网

C# SQL脚本数据中的关键字在以编程方式执行时导致问题-C

C# SQL脚本数据中的关键字在以编程方式执行时导致问题-C,c#,sql,sql-injection,sqlcommand,sql-insert,C#,Sql,Sql Injection,Sqlcommand,Sql Insert,我对sql相当陌生,并且在sql脚本中遇到了关键字造成严重破坏的问题。我正在尝试以C语言执行一个预制的.sql脚本文件列表。我当前正在将该文件读取为字符串,并使用command.ExecuteNonQuery执行它。这对于大多数脚本来说都非常有效,但我无意中遇到了一个包含关键字的脚本: INSERT INTO [thetable] SELECT '123123', 'abcabc', 'I WANT TO GO TO BED' UNION ALL SELECT '123124', 'abcdef

我对sql相当陌生,并且在sql脚本中遇到了关键字造成严重破坏的问题。我正在尝试以C语言执行一个预制的.sql脚本文件列表。我当前正在将该文件读取为字符串,并使用command.ExecuteNonQuery执行它。这对于大多数脚本来说都非常有效,但我无意中遇到了一个包含关键字的脚本:

INSERT INTO [thetable]
SELECT '123123', 'abcabc', 'I WANT TO GO TO BED'
UNION ALL
SELECT '123124', 'abcdef', 'SOOO TIRED'
基本上,当它点击GO时,命令失败

我负责创建这些插入文件,所以如果我需要以某种方式重新格式化它们,那么这是可能的;但是,其中的数据是不可协商的。而且,由于我是从一个包含许多行的文件中加载它们,因此避免这种情况的参数化似乎也不可行

在这一点上,任何帮助都将不胜感激。非常感谢

编辑以添加信息:

为了澄清,实际字符串更像是“ASVFDS4+23ef3da34sddsdf3t4g…100charslater…sd5oaygosisssdsd/sNUIGsdisd354f”。当我尝试并执行该命令时,我捕获异常,该异常表示:

"Unclosed quotation mark after character string 'ASVFDS4+23eF3da34sddsdf3d3t4g...100charslater...sd5OAy'
请注意,5OAy后面紧跟着GOsiIS…,这使我相信GO实际上是作为命令读取的,这导致它期望在该命令之前字符串结束

运行.NET3.5

编辑2 我还应该澄清一下,我目前正在分割实际的GO语句,并单独执行这些命令

i、 e

分裂,所以我执行

USE MyDatabase

分开。所以我的问题不是实际的GO语句,而是数据字符串中出现的字符“GO”

答复: 问题是我犯了一个极其愚蠢的错误。我在GO上分裂,它在命令出现的字母的中间分割命令字符串。

/掌纹


谢谢你的帮助

您需要自己识别GO,并使用它将文件分为多个批,然后分别执行每个批


使用类似于m/^\s+GO\s+$/i的正则表达式来识别GO行。

您需要自己识别GO,并使用它将文件分为多个批,然后分别执行每个批


使用类似于m/^\s+GO\s+$/i的正则表达式来识别GO行。

如果需要解析任何带有注释的Sql脚本以及带有“GO”smth GO smth等的字符串值,可以使用该工具。用于sql脚本分析的Gplex规则:

%namespace LexScanner
%option verbose, summary, noparser, unicode

%x QUOTE
%x COMMENT

%{
    static string line = "";
    static List<string> butch = new List<string>();
    enum TokenType {
        SL_COMMENT,
        ML_COMMENT,
        STRING,
        WORD,
        OTHER,
        ending
    };
%}

dotchr [^\r\n] 
eol (\r\n?|\n)
%%
\-\-[^\n]*$             { add(yytext, TokenType.SL_COMMENT); }

\/\*                    { add(yytext, TokenType.ML_COMMENT); BEGIN(COMMENT); }
<COMMENT>\*\/           { add(yytext, TokenType.ML_COMMENT); BEGIN(INITIAL); }
<COMMENT>[^\*]+         { add(yytext, TokenType.ML_COMMENT); }
<COMMENT>\*             { add(yytext, TokenType.ML_COMMENT); }

\'                      { add(yytext, TokenType.STRING); BEGIN(QUOTE); }
<QUOTE>\'\'             { add(yytext, TokenType.STRING); }
<QUOTE>[^\']+           { add(yytext, TokenType.STRING); }
<QUOTE>\'               { add(yytext, TokenType.STRING); BEGIN(INITIAL); }

[gG][oO]                { push(); }

[a-zA-Z0-9]+            { add(yytext, TokenType.WORD); }
.                       { add(yytext, TokenType.OTHER); }
\r?\n                   { add(yytext, TokenType.OTHER); }
<<EOF>>                 { push(); }
%%
push收集butch字符串以执行:

private void push()
{
    //write to the file for output control (for test only)
    using (StreamWriter str = new StreamWriter("C:\\temp\\butch.txt", true))
    {
        str.WriteLine("GO: " + line); 
    }

    butch.Add(line);
    line = "";
}
要从C代码中使用此类,您应该指定入口点。例如:

 public static List<string> ParseFile(String fileToParse)
 {
     int tok;
     Scanner scnr = new Scanner();
     scnr.SetSource(fileToParse, 0);
     do {
             tok = scnr.yylex();
         } while (tok > (int)Tokens.EOF);
     return butch;
 }

Gplex有很好的文档和如何使用它的示例

如果您需要使用'go'smth go smth等解析任何带有注释和字符串值的Sql脚本,您可以使用该工具。用于sql脚本分析的Gplex规则:

%namespace LexScanner
%option verbose, summary, noparser, unicode

%x QUOTE
%x COMMENT

%{
    static string line = "";
    static List<string> butch = new List<string>();
    enum TokenType {
        SL_COMMENT,
        ML_COMMENT,
        STRING,
        WORD,
        OTHER,
        ending
    };
%}

dotchr [^\r\n] 
eol (\r\n?|\n)
%%
\-\-[^\n]*$             { add(yytext, TokenType.SL_COMMENT); }

\/\*                    { add(yytext, TokenType.ML_COMMENT); BEGIN(COMMENT); }
<COMMENT>\*\/           { add(yytext, TokenType.ML_COMMENT); BEGIN(INITIAL); }
<COMMENT>[^\*]+         { add(yytext, TokenType.ML_COMMENT); }
<COMMENT>\*             { add(yytext, TokenType.ML_COMMENT); }

\'                      { add(yytext, TokenType.STRING); BEGIN(QUOTE); }
<QUOTE>\'\'             { add(yytext, TokenType.STRING); }
<QUOTE>[^\']+           { add(yytext, TokenType.STRING); }
<QUOTE>\'               { add(yytext, TokenType.STRING); BEGIN(INITIAL); }

[gG][oO]                { push(); }

[a-zA-Z0-9]+            { add(yytext, TokenType.WORD); }
.                       { add(yytext, TokenType.OTHER); }
\r?\n                   { add(yytext, TokenType.OTHER); }
<<EOF>>                 { push(); }
%%
push收集butch字符串以执行:

private void push()
{
    //write to the file for output control (for test only)
    using (StreamWriter str = new StreamWriter("C:\\temp\\butch.txt", true))
    {
        str.WriteLine("GO: " + line); 
    }

    butch.Add(line);
    line = "";
}
要从C代码中使用此类,您应该指定入口点。例如:

 public static List<string> ParseFile(String fileToParse)
 {
     int tok;
     Scanner scnr = new Scanner();
     scnr.SetSource(fileToParse, 0);
     do {
             tok = scnr.yylex();
         } while (tok > (int)Tokens.EOF);
     return butch;
 }

Gplex有很好的文档和如何使用它的示例

你得到的例外是什么?我非常怀疑你所遇到的问题是否与GO是否是一个关键字有关,至少正如上面的sql所示。我猜它是撇号或其他什么。在一些应用程序中,GO用作批处理分隔符。不要认为command.ExecuteNonQuery可以识别GO。您可能有一些C语言的代码可以解析SQL脚本并一次执行一个批处理,对吗?你需要寻找一种方法来解决这个问题。如果您自己编写了代码并控制了脚本文件的生成,那么您可以更改代码,使其仅在GO单独在一行上时触发新批处理。您使用的是什么数据库?如果是SQL Server,并且是开发人员版本或更高版本。尝试运行SQL Profiler以查看正在服务器上运行的SQL。同意Andrew的观点:查看正在执行的实际SQL,并通过SQL Profiler确保它是干净的@Mikael Eriksson-我在.NET中使用.ExecuteOnQuery方法专门处理GO关键字-它将其识别为批处理分隔符。MarnBeast-理想情况下,我们需要更多信息。张贴您的C代码以及!你得到的例外情况是什么?我非常怀疑你所遇到的问题是否与GO是否是一个关键字有关,至少正如上面的sql所示。我猜它是撇号或其他什么。在一些应用程序中,GO用作批处理分隔符。不要认为command.ExecuteNonQuery可以识别GO。您可能有一些C语言的代码可以解析SQL脚本并一次执行一个批处理,对吗?你需要寻找一种方法来解决这个问题。如果您自己编写了代码并控制了脚本文件的生成,那么您可以更改代码,使其仅在GO单独在一行上时触发新批处理。您使用的是什么数据库?如果是SQL Server,并且是开发人员版本或更高版本。尝试运行SQL Profiler以查看正在服务器上运行的SQL。同意Andrew的说法:查看
正在执行的实际SQL,并通过SQL探查器确保它是干净的@Mikael Eriksson-我在.NET中使用.ExecuteOnQuery方法专门处理GO关键字-它将其识别为批处理分隔符。MarnBeast-理想情况下,我们需要更多信息。张贴您的C代码以及!有趣的是,我实际上是在使用.splitnewstring[]{GO},StringSplitOptions.RemoveEmptyEntries执行此操作。这比我预期的更有效,因为我意识到它在脚本中拆分了前面提到的字符串字段,它看到了字母的去向。因此,在从String返回的命令字符串列表中,其中一个命令在字符串字段的中间被分割为一半。哎呀。将其更改为.Splitnew string[]{\r\nGO},StringSplitOptions.RemoveEmptyEntries后,问题得到了修复。有趣的是,我实际上是在使用.Splitnew string[]{GO},StringSplitOptions.RemoveEmptyEntries来执行此操作的。这比我预期的更有效,因为我意识到它在脚本中拆分了前面提到的字符串字段,它看到了字母的去向。因此,在从String返回的命令字符串列表中,其中一个命令在字符串字段的中间被分割为一半。哎呀。在将其更改为.Splitnew string[]{\r\nGO},StringSplitOptions.RemoveEmptyEntries后,问题得到了解决。请您提供更多详细信息添加、推送方法以及如何从C中使用此方法,这肯定是一种方法,但我不是Lex的专家。。。谢谢!你可以提供更多的细节,添加,推送方法,以及如何从C使用它,这是肯定的方式去,但我不是一个专家在所有与莱克斯。。。谢谢!
gplex sqlparser.lex