我在 MySQL 中使用递归存储过程来生成一个名为的临时表id_list,但我必须在后续选择查询中使用该过程的结果,因此我无法DROP在过程中使用临时表...
BEGIN;
/* generates the temporary table of ID's */
CALL fetch_inheritance_groups('abc123',0);
/* uses the results of the SPROC in the WHERE */
SELECT a.User_ID
FROM usr_relationships r
INNER JOIN usr_accts a ON a.User_ID = r.User_ID
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
GROUP BY r.User_ID;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
调用过程时,第一个值是我想要的分支的顶部ID,第二个值是tier过程在递归期间使用的。在递归循环之前,它会检查是否tier = 0运行:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT …Run Code Online (Sandbox Code Playgroud) 我有一个查询需要相当长的时间(大约 1100 万个观察值)和三个连接(我无法阻止它进行检查)。其中一个连接是使用临时表。
当我使用其中包含主键的表中的数据创建临时表时,新表是否会继承索引,或者我是否必须在新临时表中显式创建索引(使用父表中的主键)桌子)?
我们在开发过程中遇到了一个奇怪的问题,正在寻找有关SELECT INTO临时表上的自死锁问题的解释。
我们有一个例程将一些相当复杂的 JSON 文档转换为表格形式。我们目前正在使用 来完成此任务OPENJSON,通常效果很好。
这种转变是在触发器的背景下发生的。当向表中插入一行或多行时,会生成一组 JSON 文档,将其存储在单个变量中,并传递到以下例程中。它看起来像这样:
SELECT
a.[ID],
b.[Some stuff here...]
INTO #MyTempTable
FROM OPENJSON(@MyJSONDocuments)
WITH (
ID VARCHAR(40),
nestedDocument NVARCHAR(MAX) AS JSON) a
CROSS APPLY OPENJSON(nestedDocument ,'$') b
Run Code Online (Sandbox Code Playgroud)
当我们在 SSMS 中运行它时,它工作得很好。临时表已生成并填充,没有问题。当我们将其移至触发器并仅将一行插入基础表(即@MyJSONDocuments单个文档的数组)时,它也可以正常工作。当我们插入两行或更多行,并且@MyJSONDocuments数组中包含多个文档时,我们会遇到可怕的情况:
Transaction (Process ID x) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Run Code Online (Sandbox Code Playgroud)
当我们将SELECT INTO语句包装在 SSMS 中的 aBEGIN TRAN / COMMIT …
sql-server json temp-tables sqlperformance database-deadlocks
我正在尝试在过程中创建并填充临时表,以保存我正在使用的数据的一些中间状态。
我创建了一个示例代码来解释我想要做什么:
CREATE OR REPLACE PROCEDURE etl.my_test_procedure()
LANGUAGE sql
AS
$$
CREATE TEMP TABLE IF NOT EXISTS my_temp(
var1 VARCHAR(255),
var2 VARCHAR(255)
) ON COMMIT DROP;
INSERT INTO my_temp (
var1,
var2
)
SELECT
table_schema,
column_name
FROM information_schema.columns;
SELECT
*
FROM my_temp
$$
Run Code Online (Sandbox Code Playgroud)
尝试创建此存储过程时,数据库返回以下错误消息: 错误:关系“my_temp”不存在第 10 行:INSERT INTO my_temp (^ SQL 状态:42P01 字符:171
PD:我的 Postgres 版本是 13.3
当我创建临时表时,我收到一条错误消息,告诉我临时表已经存在.临时表对于会话是唯一的,所以看起来我的连接没有正确关闭,我认为它可能与我在using语句中的return语句有关.
我有以下代码:
using (IDbConnection connection = dbConnectionHandler.CreateConnection())
{
connection.Open();
CreateATempTable();
PopulateTempTable();
DataSet ds = CallStoredProcThatUsesTempTable();
return ds;
}
Run Code Online (Sandbox Code Playgroud)
我在几个地方使用这种代码来创建一个具有相同名称的临时表.
不幸的是,我收到以下错误:There is already an object named '#MyTempTable' in the database.
现在,我知道临时表对于会话是唯一的,因此一旦会话关闭它就会消失.
我认为有三件事可能会导致这种情况......
有谁知道它是哪一个?或者如果它没有想到的东西?
基本上我希望能够基于现有表动态创建临时表,然后将值插入临时表,并选择插入的值.
我有一个部分,我可以创建临时表工作得很好,只是插入和选择形式它不是很好.
这是我目前的代码.
declare @table table
(
OrdinalPosition int,
ColumnName nvarchar(255),
DataType nvarchar(50),
MaxChar int,
Nullable nvarchar(5)
)
declare @i int
declare @count int
declare @colname nvarchar(255), @datatype nvarchar(50), @maxchar int
declare @string nvarchar(max)
declare @tblname nvarchar(100)
set @tblname='Projects'
set @string='create table #' + @tblname + ' ('
insert into @table
(
OrdinalPosition,
ColumnName,
DataType,
MaxChar,
Nullable
)
SELECT
ORDINAL_POSITION ,
COLUMN_NAME ,
DATA_TYPE ,
CHARACTER_MAXIMUM_LENGTH ,
IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tblname
set @i=1
select @count=count(*) from @table …Run Code Online (Sandbox Code Playgroud) 比较以下存储过程:
CREATE PROCEDURE testProc1
AS
SELECT * INTO #temp FROM information_schema.tables
SELECT * FROM #temp
GO
CREATE PROCEDURE testProc2
AS
EXEC('SELECT * INTO #temp FROM information_schema.tables')
SELECT * FROM #temp
GO
Run Code Online (Sandbox Code Playgroud)
现在,如果我运行testProc1,它可以工作,并且#temp似乎只在该调用期间存在.但是,testProc2似乎根本不起作用,因为我收到了Invalid object name '#temp'错误消息.
为什么区别,SELECT * INTO如果源表名是存储过程的参数并且可以具有任意结构,我如何使用临时表?
请注意,我正在使用Microsoft SQL Server 2005.
鉴于:
存储过程中的代码:
select bleh
into #tblTemp
from FunctionThatReturnsTable('some','params')
-- do some stuff
drop table #tblTemp
-- Error on this command:
-- 'There is already an object named '#tblTemp' in the database.'
select bleh
into #tblTemp
from FunctionThatReturnsTable('some','other params')
Run Code Online (Sandbox Code Playgroud)
问题:
我无法重新创建这个临时表.我的工作是使用#tmpTable1,#tmpTable2,#tempTable3等.有没有办法解决这个问题?每次只使用一个临时表会很不错.
如果没有,这是什么原因?
我想获取临时表中的列列表,类似于INFORMATION_SCHEMA.columns视图.但是,这段代码:
select *
from tempdb.INFORMATION_SCHEMA.columns
where TABLE_CATALOG = 'tempdb'
and TABLE_NAME like '#myTemporaryTable%'
Run Code Online (Sandbox Code Playgroud)
每列和每个会话返回一行.这样做是否安全:
select distinct column_name,data_type
from tempdb.INFORMATION_SCHEMA.columns
where TABLE_CATALOG = 'tempdb'
and TABLE_NAME like '#myTemporaryTable%'
Run Code Online (Sandbox Code Playgroud)
我有一种感觉它不是,即使你收紧了类似的条款,所以它不会匹配myTemporaryTable和myTemporaryTable2.
我正在创建一个处理临时表(#attributeType)的触发器.由于触发器可以多次调用,我想确定并检查临时表#attributeType是否仍然存在.
这是我在触发器体中检查临时表的代码:
IF OBJECT_ID('tempdb..#attributeType') IS NOT NULL
BEGIN
DROP TABLE #attributeType
SELECT * INTO #attributeType
FROM attributeType
PRINT 'IN IF'+ CAST(OBJECT_ID('tempdb..#attributeType') AS NVARCHAR(80))
END
ELSE
BEGIN
SELECT * INTO #attributeType
FROM attributeType
PRINT 'IN ELSE'+ CAST(OBJECT_ID('tempdb..#attributeType') AS NVARCHAR(80))
END
Run Code Online (Sandbox Code Playgroud)
当我通过使用F5选择代码来测试代码时,我收到此错误消息,指出#attributeType临时表存在:
Msg 2714, Level 16, State 1, Line 11
There is already an object named '#attributeType' in the database.
Run Code Online (Sandbox Code Playgroud)
我知道在存储过程中,一旦sp结束就会删除#tempTables,但我仍然无法理解为什么我的代码错了?
注意当我注释掉ELSE块时代码有效.
temp-tables ×10
sql-server ×5
t-sql ×3
mysql ×2
sql ×2
c# ×1
dbconnection ×1
exec ×1
exists ×1
indexing ×1
insert ×1
json ×1
memory-table ×1
postgresql ×1
triggers ×1