【问题标题】:multiple SQL commands. Good style?多个 SQL 命令。好作风?
【发布时间】:2014-04-03 02:17:55
【问题描述】:

我有一个运行良好的 asp.net 应用程序。在我的代码中,我有以下几行

using (SqlConnection con = new SqlConnection(CS))
{
    SqlCommand getGenreId = new SqlCommand("Select ID from tblGenre WHERE Genre=@newGenre;", con);
    getGenreId.Parameters.AddWithValue(@"newGenre", newGenre);
    SqlCommand cmd = new SqlCommand("UPDATE tblSong SET Title=@newTitle, ArtistId=@newArtistId, GenreId=@newGenreId WHERE (ID = @songId);", con);
    cmd.Parameters.AddWithValue(@"newTitle", newTitle);
    cmd.Parameters.AddWithValue(@"newArtistId", newArtistId);
    cmd.Parameters.AddWithValue(@"songId", songId);
    con.Open();
    newGenreId = (int)getGenreId.ExecuteScalar();
    cmd.Parameters.AddWithValue(@"newGenreId", newGenreId);
    cmd.ExecuteNonQuery();
}

我知道数据库连接是宝贵的资源,我在使用它们时应该小心。 (尽可能晚开放,并确保它们也将关闭)

我现在的问题是这段代码被认为是不好的风格,因为我打开连接然后有一个 sql 查询来获取一个 ID,然后有另一个 sql 查询来插入一条记录。

谢谢!

【问题讨论】:

  • 会更好地利用资源放入存储过程中。只需将信息传递给数据库,让它更新、选择、插入其他需要的内容,而不占用任何网络。
  • 正如 Vladimir 的回答所表明的,将 SQL 语句转换为存储过程将带来更好的性能,更重要的是,提供一定程度的 SQL 注入攻击保护。
  • 不使用参数化查询也是一种防止 sql 注入的方法吗?

标签: asp.net sql sql-server


【解决方案1】:

如果您转换为使用存储过程,则可以消除 1 次往返,从而减少网络流量并可能提高性能。

using (SqlCommand cmd = new SqlCommand("Update_tblSong", con);
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@newGenre", newGenre);
    cmd.Parameters.AddWithValue("@newTitle", newTitle);
    cmd.Parameters.AddWithValue("@newArtistId", newArtistId);
    cmd.Parameters.AddWithValue("@songId", songId);
    cmd.ExecuteNonQuery();
}

Proc 会这样,我估计你的可变大小。

  CREATE PROC Update_tblSong
    (
     @newGenre VARCHAR(25)
    ,@newTitle VARCHAR(50)
    ,@newArtistID INT
    ,@songID INT
    )
  AS
    BEGIN 
        SET NOCOUNT ON;
        DECLARE @NewGenreID INT;

        SELECT @NewGenreID = ID
            FROM tblGenre
            WHERE Genre = @newGenre; 

        UPDATE tblSong
            SET Title = @newTitle
               ,ArtistId = @newArtistId
               ,GenreId = @NewGenreID
            WHERE ( ID = @songId )
    END;

【讨论】:

    【解决方案2】:

    总体而言,您的代码流看起来不错,您正在使用单个连接来执行多个 (相关) 命令。

    您可以通过将命令对象包含在using statement 中来进一步改进它。由于它们实现了IDisposable 接口,就像您的连接对象一样。

    using (SqlConnection con = new SqlConnection(CS))
    {
        con.Open();
        using (SqlCommand getGenreId = new SqlCommand("Select ID from tblGenre WHERE Genre=@newGenre;", con))
        {
            getGenreId.Parameters.AddWithValue(@"newGenre", newGenre);
            newGenreId = (int)getGenreId.ExecuteScalar();
        }
        using (SqlCommand cmd = new SqlCommand("UPDATE tblSong SET Title=@newTitle, ArtistId=@newArtistId, GenreId=@newGenreId WHERE (ID = @songId);", con))
        {
            cmd.Parameters.AddWithValue(@"newTitle", newTitle);
            cmd.Parameters.AddWithValue(@"newArtistId", newArtistId);
            cmd.Parameters.AddWithValue(@"songId", songId);
            cmd.Parameters.AddWithValue(@"newGenreId", newGenreId);
            cmd.ExecuteNonQuery();
        }
    }
    

    【讨论】:

      【解决方案3】:

      为什么不对您的 SQL 使用带有子查询的单个查询?

      UPDATE tblSong SET Title = @newTitle, ArtistId = @newArtistId, GenreId = (Select top 1 ID from tblGenre WHERE Genre=@newGenre ORDER BY Genre) WHERE (ID = @songId);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多