如何在 C# 中直接执行 SQL 查询?

Posted

技术标签:

【中文标题】如何在 C# 中直接执行 SQL 查询?【英文标题】:How to directly execute SQL query in C#? 【发布时间】:2014-03-09 16:17:43 【问题描述】:

好的,我有一个旧的批处理文件可以满足我的需要。但是,如果没有新的管理,我们将无法再运行批处理文件,因此我需要使用 C# 启动。

我正在使用 Visual Studio C#,并且已经为我需要构建的应用程序设置了表单。 (我边走边学)

这是我需要在 C# 中完成的任务(这是批处理内容)

sqlcmd.exe -S .\PDATA_SQLEXPRESS -U sa -P 2BeChanged! -d PDATA_SQLEXPRESS  -s ; -W -w 100 -Q "SELECT tPatCulIntPatIDPk, tPatSFirstname, tPatSName, tPatDBirthday  FROM  [dbo].[TPatientRaw] WHERE tPatSName = '%name%' "

基本上它使用SQLCMD.exe 和已经存在的名为PDATA_SQLExpress 的数据源。 我已经搜索并接近了,但我仍然不知道从哪里开始。

【问题讨论】:

您是要执行现有的批处理文件,还是要连接到数据库并直接在 C# 中运行查询? 【参考方案1】:

要直接从 C# 中执行命令,您可以使用 SqlCommand 类。

使用参数化 SQL(以避免注入攻击)的快速示例代码可能如下所示:

string queryString = "SELECT tPatCulIntPatIDPk, tPatSFirstname, tPatSName, tPatDBirthday  FROM  [dbo].[TPatientRaw] WHERE tPatSName = @tPatSName";
string connectionString = "Server=.\PDATA_SQLEXPRESS;Database=;User Id=sa;Password=2BeChanged!;";

using (SqlConnection connection = new SqlConnection(connectionString))

    SqlCommand command = new SqlCommand(queryString, connection);
    command.Parameters.AddWithValue("@tPatSName", "Your-Parm-Value");
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    try
    
        while (reader.Read())
        
            Console.WriteLine(String.Format("0, 1",
            reader["tPatCulIntPatIDPk"], reader["tPatSFirstname"]));// etc
        
    
    finally
    
        // Always call Close when done reading.
        reader.Close();
    

【讨论】:

nate,我想我现在可能倾向于这个方向。到目前为止,它似乎可以工作,但是在运行它时我得到了一个未处理的异常。无效的对象 namd 'dbo.TPatientRaw'。 @Reracer68 我怀疑 SQL 查询有问题。尝试在查询中使用表名TPatientRaw,而不是完整的[dbo].[Table] 知道了!不得不给一个数据库使用,因为有多个!奇迹般有效。甚至指出它将结果输出到富文本框。 在SqlConnection 上使用 而不是在SqlDataReader 上是否有任何原因? @Fa773NM0nK 除了样品之外没有什么好的理由,我忘记了。对于任何想知道的人,这里有一个很好的阅读为什么它是一个好主意:***.com/questions/3386770/using-on-sqldatareader【参考方案2】:

这样的事情就足够了,做你的批处理文件正在做的事情(将结果集作为分号分隔的文本转储到控制台):

// sqlcmd.exe
// -S .\PDATA_SQLEXPRESS
// -U sa
// -P 2BeChanged!
// -d PDATA_SQLEXPRESS
// -s ; -W -w 100
// -Q "SELECT tPatCulIntPatIDPk, tPatSFirstname, tPatSName, tPatDBirthday  FROM  [dbo].[TPatientRaw] WHERE tPatSName = '%name%' "

DataTable dt            = new DataTable() ;
int       rows_returned ;

const string credentials = @"Server=(localdb)\.\PDATA_SQLEXPRESS;Database=PDATA_SQLEXPRESS;User ID=sa;Password=2BeChanged!;" ;
const string sqlQuery = @"
  select tPatCulIntPatIDPk ,
         tPatSFirstname    ,
         tPatSName         ,
         tPatDBirthday
  from dbo.TPatientRaw
  where tPatSName = @patientSurname
  " ;

using ( SqlConnection connection = new SqlConnection(credentials) )
using ( SqlCommand    cmd        = connection.CreateCommand() )
using ( SqlDataAdapter sda       = new SqlDataAdapter( cmd ) )

  cmd.CommandText = sqlQuery ;
  cmd.CommandType = CommandType.Text ;
  connection.Open() ;
  rows_returned = sda.Fill(dt) ;
  connection.Close() ;


if ( dt.Rows.Count == 0 )

  // query returned no rows

else


  //write semicolon-delimited header
  string[] columnNames = dt.Columns
                           .Cast<DataColumn>()
                           .Select( c => c.ColumnName )
                           .ToArray()
                           ;
  string   header      = string.Join("," , columnNames) ;
  Console.WriteLine(header) ;

  // write each row
  foreach ( DataRow dr in dt.Rows )
  

    // get each rows columns as a string (casting null into the nil (empty) string
    string[] values = new string[dt.Columns.Count];
    for ( int i = 0 ; i < dt.Columns.Count ; ++i )
    
      values[i] = ((string) dr[i]) ?? "" ; // we'll treat nulls as the nil string for the nonce
    

    // construct the string to be dumped, quoting each value and doubling any embedded quotes.
    string data = string.Join( ";" , values.Select( s => "\""+s.Replace("\"","\"\"")+"\"") ) ;
    Console.WriteLine(values);

  


【讨论】:

【参考方案3】:

重要提示:除非您完全信任用户,否则不应连接 SQL 查询。查询连接涉及 SQL 注入被用来接管世界、...khem、您的数据库的风险。

如果您不想详细说明如何使用SqlCommand 执行查询,那么您可以像这样调用相同的命令行:

string userInput = "Brian";
var process = new Process();
var startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = string.Format(@"sqlcmd.exe -S .\PDATA_SQLEXPRESS -U sa -P 2BeChanged! -d PDATA_SQLEXPRESS  
     -s ; -W -w 100 -Q "" SELECT tPatCulIntPatIDPk, tPatSFirstname, tPatSName,
     tPatDBirthday  FROM  [dbo].[TPatientRaw] WHERE tPatSName = '0' """, userInput);

process.StartInfo = startInfo;
process.Start();

只需确保将每个双引号 " 转义为 ""

【讨论】:

哇,真快!这正是我想要的! 快速提问。我将如何向其中添加用户输入?从一个名为 GFIDuserinput 的文本框中以相同的形式说?在实际的 sqlcmd.exe 字符串中,%name% 是需要提供的。 @Reracer68 - 在您上面提到的情况下,您可以连接文本框的 .Text 属性中的 %name% 值。 我不建议直接连接用户输入,除非你想容易受到 SQL 注入的攻击。 现在这不是一个真正的问题。这些是封闭的网络,没有像这样的真正安全威胁。不过这很酷。我应该可以从这里拿走它。非常感谢!

以上是关于如何在 C# 中直接执行 SQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章

C#,winfom,数据库为access.如何把sql查询结果直接保存在数组中?不是通过循环一个值一个值的赋予。

如何在 LINQ 和 Lambda 表达式 LINQ C# 上正确执行 SQL 查询

如何通过单击按钮 [C#] 执行 2 个 sql 查询

如何从 C# 测试 sql 查询执行? [复制]

如何在 C# 中创建动态参数化 SQL 查询字符串

C# 调用一个方法,内有一个参数,执行SQL查询语句,并将结果返回,该方法如何写?