可可因 發表於 2023-11-4 00:00:00

带参数的sql和不带参数的sql存储过程区别

<p>
        带参数的sql语句,在数据库端,执行的是<br>
        exec sp_executesql<br>
        eg:<br><br>
        exec sp_executesql N'insert into LCS_Sys_Model (,,,) values ( @Model_GUID,@Model_Name,@Model_Desp,@Model_IsSys)', N'@Model_GUID uniqueidentifier,@Model_Name nvarchar(50),@Model_Desp nvarchar(500),@Model_IsSys bit', @Model_GUID = 'F3CD1369-58C0-4A1F-AF88-05FCF734E079', @Model_Name = N'测试实体模型', @Model_Desp = N'实体模型描述', @Model_IsSys = 0<br><br><br>
        没有带值的sql语句。其执行是直接的sql语句。<br>
        insert into lcs_Sys_Model (,,,) values ( 'F3CD1369-58C0-4A1F-AF88-05FCF734E079','name','desp',1 )<br><br><br>
        看上面的执行代码,你会不会认为是下面的高效啊?说实话我也没有仔细测试过。可是据我所知,sqlserver能够缓存参数信息和sql编译后的信息,第一句带参 数的sql因为前面一部是不变的(红色部分)。所以能够缓存起来(就像执行存储过程一样)。而下面的一句sql。因为value后面的值总是不固定,因此 sqlserver总是认为是不同的sql语句。因此每次都要重新编译生成。<br><br>
        以上结论来源于下面的测试代码。<br><br>
        System.Data.SqlClient.SqlParameter[] parameters = {<br>
        new SqlParameter("@Model_GUID", SqlDbType.UniqueIdentifier),<br>
        new SqlParameter("@Model_Name", SqlDbType.NVarChar,50),<br>
        new SqlParameter("@Model_Desp", SqlDbType.NVarChar,500),<br>
        new SqlParameter("@Model_IsSys", SqlDbType.Bit)<br>
        };<br>
        parameters.Value = new Guid("F3CD1369-58C0-4A1F-AF88-05FCF734E079");<br>
        parameters.Value = "测试实体模型";<br>
        parameters.Value = "实体模型描述";<br>
        parameters.Value = false;<br><br><br><br>
        string connStr = @"Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=officially;Data Source=LCSNB"SQL2K";<br>
        string cmdStr = "insert into LCS_Sys_Model (,,,) values ( @Model_GUID,@Model_Name,@Model_Desp,@Model_IsSys)";<br><br>
        System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr);<br>
        System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(cmdStr);<br><br>
        cmd.Connection = conn;<br>
        foreach (var item in parameters)<br>
        {<br>
        cmd.Parameters.Add(item);<br>
        }<br><br><br>
        cmd.Connection.Open();<br>
        cmd.ExecuteNonQuery();<br>
        //第一次执行结束<br>
        cmd.Parameters.Clear();<br>
        cmd.CommandText = "SELECT SCOPE_IDENTITY()";<br><br>
        //System.Diagnostics.Debug.Assert(cmd.ExecuteScalar()==null);<br><br>
        Console.WriteLine(cmd.ExecuteScalar().ToString());<br>
        //第二次执行结束<br>
        cmd.Connection.Close();<br><br>
        Console.WriteLine("第一次测试结束");<br>
        Console.Read();<br><br>
        cmd.CommandText = "insert into lcs_Sys_Model (,,,) values ( 'F3CD1369-58C0-4A1F-AF88-05FCF734E079','name','desp',1 )";<br>
        cmd.Connection.Open();<br>
        cmd.ExecuteNonQuery();<br><br>
        cmd.CommandText = "SELECT SCOPE_IDENTITY()";<br>
        Console.WriteLine(cmd.ExecuteScalar().ToString());<br>
        cmd.Connection.Close();<br>
        Console.WriteLine("第二次测试结束");<br>
        Console.Read();<br><br><br>
        本来想用参数化的sql插入一条记录再取回自增的值的。发现数据库端是这个执行方式。那就没戏啦。。。只能改变sql语句。把自增放到sql的最后去取啦。。<br><br>
        exec sp_executesql N'insert into LCS_Sys_Model (,,,) values ( @Model_GUID,@Model_Name,@Model_Desp,@Model_IsSys)', N'@Model_GUID uniqueidentifier,@Model_Name nvarchar(50),@Model_Desp nvarchar(500),@Model_IsSys bit', @Model_GUID = 'F3CD1369-58C0-4A1F-AF88-05FCF734E079', @Model_Name = N'测试实体模型', @Model_Desp = N'实体模型描述', @Model_IsSys = 0<br><br>
        SELECT SCOPE_IDENTITY()<br><br><br>
        在查询分析器里面最后确认运行一下。。。这二个是不同的范围的,是取不到值的。。<br><br><br>
        最后提配一点,为了性能和安全,我们在写存储过程的时候也要使用<br><br>
        exec sp_executesql '带参数的sql语句','参数定义语句,多个参数用,号分隔',参数赋值1,参数赋值2,参数赋值3```<br><br>
        来执行我们sql语句,看到很多分页存储过程都是直接拼凑sql语句然后用exec('')执行起来了,这个从效率和安全上面来说,都是不推荐的。</p>
頁: [1]
查看完整版本: 带参数的sql和不带参数的sql存储过程区别