数据库
首页 > 数据库> > SqlDataAdapter是否打开自己的连接?

SqlDataAdapter是否打开自己的连接?

作者:互联网

SqlDataAdapter是否打开自己的连接?

        private DataTable UpdateOxa(ProductCatalogSyncData syncDataModel, string connectionString)
    {
        var ds = syncDataModel.SyncDataSet;
        var dtResults = new DataTable("BillingIds");
        var syncConfig = syncDataModel.XDataMapping;
        string EntityName;


        string queryString =
                    @"         
                                IF OBJECT_ID('#CRM2Oxa_ID_MAPPING') IS NOT NULL
                               DROP TABLE #CRM2Oxa_ID_MAPPING


                               CREATE TABLE #CRM2Oxa_ID_MAPPING(
                                [EntityName][nvarchar](1000) NULL,

                                   [TableName][nvarchar](1000) NULL,

                                   [CRMID][uniqueidentifier] NULL,

                                   [OxaID][int] NOT NULL,

                                   [CRMColumnName][nvarchar](1000) NULL
                               ) ";
        var listOfSqlCommands = new List<SqlCommand>();
        var OxaConnection = new SqlConnection(connectionString);

        try
        { 


            OxaConnection.Open();

            using (var createTempTableCommand = new SqlCommand(queryString, OxaConnection))
            {
                createTempTableCommand.ExecuteNonQuery();
            }

                foreach (DataTable dt in ds.Tables)
                {
                    EntityName =
                        StringDefaultIfNull(
                            syncConfig.Root.XPathSelectElement("./entity[@name='" + dt.TableName + "']"),
                            "OxaTableName").Substring(3);

                    var OxaCommand = new SqlCommand();

                    OxaCommand.CommandType = CommandType.StoredProcedure;
                    OxaCommand.CommandText = "Oxa720_P_" + EntityName + "Sync";

                    var entityNameParam = new SqlParameter("@EntityName", dt.TableName);
                    OxaCommand.Parameters.Clear();
                    OxaCommand.Parameters.Add(entityNameParam);
                    var tblParam = new SqlParameter("@O720_" + EntityName, SqlDbType.Structured);
                    tblParam.Value = dt;
                    OxaCommand.Parameters.Add(tblParam);
                    OxaCommand.Connection = OxaConnection;

                    listOfSqlCommands.Add(OxaCommand);
                }



                foreach (var command in listOfSqlCommands)
                {
                    using (var da = new SqlDataAdapter(command))
                    {
                        da.Fill(dtResults);
                    }

                }
        }
        finally
        {
            OxaConnection.Close();
        }
        return dtResults;

    }

我从数据库收到一条消息,提示表#temptable不存在.

SqlDataAdapter是否打开自己的连接?也许这就是为什么它看不到本地临时表?

解决方法:

如果您的SqlConnection已经打开,则SqlDataAdapter应该按原样使用它(即不关闭/打开它).

关于为什么存储的proc无法看到临时表的一种可能性是ADO.NET使用sp_executesql调用执行了您的第一个SqlCommand(用于创建临时表).这意味着将在存储的proc sp_executesql的范围内创建临时表,即使使用相同的连接,后续命令也看不到该临时表.要进行检查,您可以运行Sql Profiler跟踪-如果您看到sp_executesql用于您的第一个SqlCommand,那么您将遇到问题.

此评论位于:
Sql Server temporary table disappears可能是相关的:

I honestly think it has to do with the way the SqlCommand text is
structured. If it’s a simple select into, with no parameters, then it
may be run as a simple select statement, so it won’t be wrapped in an
SqlProcedure like ‘sp_executesql’, so it will remain visible to
subsequent queries using that same SqlCommand and SqlConnection
object. On the other hand, if it’s a complex statement, the temp table
may be created within a stored procedure like ‘sp_executesql’, and
will go out of scope by the time the command is finished. – Triynko
Feb 25 ’15 at 21:10

如果ADO.NET确实在为表创建命令使用sp_executesql,则可以通过将命令分解为2个SqlCommands来诱使它不使用它:一个删除临时表(如果存在),另一个删除临时表.创建临时表.

编辑:在旁注,此代码:

IF OBJECT_ID('#CRM2Oxa_ID_MAPPING') IS NOT NULL
       DROP TABLE #CRM2Oxa_ID_MAPPING

应该可能是:

IF OBJECT_ID('tempdb..#CRM2Oxa_ID_MAPPING') IS NOT NULL
       DROP TABLE #CRM2Oxa_ID_MAPPING

否则,OBJECT_ID(‘#CRM2Oxa_ID_MAPPING’)将始终为null(除非您已经在临时数据库中).

编辑2:这是一些对我有用的简单代码:

        DataSet ds = new DataSet();

        using(SqlConnection conn = new SqlConnection("YourConnectionString"))
        {
            conn.Open();

            string str = "if object_id('tempdb..#mytest') is not null drop table #mytest; create table #mytest (id int)";

            // create temp table
            using(SqlCommand cmdc = new SqlCommand(str, conn))
            {
                cmdc.ExecuteNonQuery(); 
            }

            // insert row
            using (SqlCommand cmdi = new SqlCommand("insert #mytest (id) values (1)", conn))
            {
                cmdi.ExecuteNonQuery();
            }

            // use it
            using (SqlCommand cmds = new SqlCommand("dbo.mytestproc", conn))
            {
                cmds.CommandType = CommandType.StoredProcedure;
                cmds.Parameters.Add("@id", SqlDbType.Int).Value = 1;
                cmds.Connection = conn;

                using (SqlDataAdapter da = new SqlDataAdapter(cmds))
                {
                    da.Fill(ds);
                }
            } 

            // clean up - drop temp table
            string strd = "if object_id('tempdb..#mytest') is not null drop table #mytest";
            using (SqlCommand cmdd = new SqlCommand(strd, conn))
            {
                cmdd.ExecuteNonQuery();
            }
        }

        MessageBox.Show("done, num rows " + ds.Tables[0].Rows.Count);

存储的过程如下所示:

create proc dbo.mytestproc(@id int)
as
select * from #mytest where id = @id
GO

最后,它显示:“ done,num rows 1”

标签:ado-net,sql,c,sql-server,tsql
来源: https://codeday.me/bug/20191026/1937095.html