我正在尝试使用C#中的dapper执行一系列SQL * Server步骤。第一步将创建一个临时表并将其填充。以下步骤从临时表中查询数据。创建/填充似乎已成功运行,但是来自临时表的第一个查询失败说:
“无效的对象名称’#GetPageOfGlobalUsers’。”
using (SqlConnection connection = DBConnectionProvider.CreateConnection()) { ... misc setup stuff... connection.Execute(@" create table #GetPageOfGlobalUsers(row int, EmailAddress nvarchar(max), LastName nvarchar(max), FirstName nvarchar(max), Id uniqueidentifier) insert into #GetPageOfGlobalUsers SELECT ROW_NUMBER() OVER (order by LastName, FirstName, EmailAddress) row, EmailAddress, LastName, FirstName, Id FROM Users WHERE LastName like @search or FirstName like @search or EmailAddress like @search ", new { search = search } ); int count = connection.Query<int>(@" SELECT count(*) from tempdb..#GetPageOfGlobalUsers ").Single<int>(); ... more queries from the temp table follow
上面,执行有效,但是查询失败,并出现了我上面提到的错误。(请注意,无论是否使用“ tempdb ..”前缀,我都会遇到相同的错误。)如果我改为创建一个永久表(即,如果删除前导散列),或者使它成为全局临时表(即,前缀)带有两个哈希的名称),一切正常。
我的理解是,用单个哈希命名的临时表受连接持续时间的限制,所以我不知道发生了什么。但是我敢肯定有人可以告诉我!
(顺便说一句,如果没有人告诉我“不要那样做”,除非根本做不到,我将不胜感激。)
我不完全了解发生了什么,但是我可以通过在自己的Execute中创建临时表来解决此问题,而不是像在代码中同时创建表和填充表的Execute中那样显示在我的问题中。
即,以下工作:
connection.Execute(@" create table #PagesOfUsers(row int, EmailAddress nvarchar(max), LastName nvarchar(max), FirstName nvarchar(max), Id uniqueidentifier)" ); connection.Execute(@" insert into #PagesOfUsers SELECT ROW_NUMBER() OVER (order by LastName, FirstName, EmailAddress) row, EmailAddress, LastName, FirstName, Id FROM Users WHERE LastName like @search or FirstName like @search or EmailAddress like @search ", new { search = search } ); int count = connection.Query<int>(@" SELECT count(*) from #PagesOfUsers ").Single<int>();
这并不可怕,但是很不方便。值得注意的是,我宁愿根本不必 _显式_创建临时表。确实,我最初将create / populate操作编码为SELECT INTO,因此不必逐项列出临时表的列。但这在随后的查询中也遇到了“无效对象”错误,因此我尝试使用显式的CREATETABLE来查看它是否有所作为,并在发现问题后在此处张贴了我的问题。
我看到的行为是,当在同一Execute中创建并填充临时表时,表面看来成功后,实际上并没有在tempdb中。这让我想知道原始代码中的Execute是否在做任何事情!据我所知,这相当于没有采取任何行动。