在 SQL Server 中,名称类似于 #temp 的临时表具有本地作用域。如果您在会话中创建它们,会话中的所有内容都可以看到它们,但不能在会话之外看到。如果在存储过程中创建这样的表,则作用域是该过程的本地范围。因此,当 proc 退出时,该表消失了。
我知道的唯一替代方法是使用名称类似于##temp 的表。这些是临时的,但在服务器范围内可见。因此,如果我在会话中创建表,隔壁办公室的 Bob 也会看到它们。
我正在寻找的是中间的某个地方,因此我可以在存储过程中创建表,并且即使在存储过程退出后,该表也可用于我的会话。我能找到的最近的方法是创建只有一个字段的表,然后在存储过程中更改它。不过,这似乎有点混乱。
假设我有一个函数,我需要在其中执行多个操作,所有操作都取决于一个查询的结果.我能找到的所有东西都表明我需要在程序之外定义一个临时表,我不想这样做.
我想做类似以下的事情:
create or replace function f_example(
a_input in number
)
return varchar2 is
begin
create local temporary table tempIDs
(
testID number(6, 0)
, testValue number(8,0)
);
//select data from tableFoo that will be overwritten by a_input into tempIDs
//update data in tableFoo with a_input & store old data in another tableFoo field
end f_example;
Run Code Online (Sandbox Code Playgroud)
此语法不起作用.Oracle不允许在函数内部使用"创建".
我不是一个真正的数据库程序员 - 我习惯于使用C#和Java.在这种情况下,我会将我的值存储在方法完成时超出范围的本地数组(或其他)中.在Oracle SQL中是否合法地无法做到这样的事情?
我知道在 SQL 中创建和使用游标既不安全也不高效,但有时它是唯一的选择。现在这是我唯一的选择。
我的问题不是如何避免使用游标,而是如果游标仅在存储过程中动态创建的临时表上运行,那么安全性如何以及会引发哪些性能问题。我知道游标的运行速度比设置操作慢,并且会在它们正在迭代的表上加锁。我的临时表是一个相对较小的表,仅包含一个 int 类型的字段和最多 50 条记录。
DECLARE @pD int
DECLARE CurDB CURSOR FOR
SELECT pD FROM #mD
open CurDB
fetch next from CurDB into @pD
etc...
Run Code Online (Sandbox Code Playgroud) 我有 2 个组,我试图找到它们的交集(需要 2 列匹配),我发现加入 2 个临时表的性能比仅用一个临时表加入原始表的性能要慢 50 倍。这对我来说毫无意义,所以也许有人可以启发我?
这是我编写 2 个临时表版本的方式:
CREATE TEMPORARY TABLE attendees (
event_id SMALLINT(5) UNSIGNED,
person_id INT(10) UNSIGNED NOT NULL,
KEY(event_id),
KEY(person_id)
);
INSERT INTO attendees (event_id, person_id)
SELECT event_id, person_id
FROM attendance WHERE year=2013
GROUP BY event_id, person_id;
CREATE TEMPORARY TABLE invitees (
event_id SMALLINT(5) UNSIGNED,
person_id INT(10) UNSIGNED NOT NULL,
KEY(event_id),
KEY(person_id)
);
INSERT INTO invitees (event_id, person_id)
SELECT event_id, person_id
FROM invitations WHERE year=2013
GROUP BY event_id, person_id;
SELECT i.event_id, COUNT(DISTINCT i.person_id) …Run Code Online (Sandbox Code Playgroud) 通常,在测试存储过程代码以进行改进或更改请求时,我发现自己将代码块直接复制并粘贴到 Management Stuido 中,调整变量并运行它们。
但是,很多时候代码依赖于存储过程运行期间创建的临时表(而不是表变量)。在正常的操作过程中,当存储过程完成执行时,这些表就会被释放,但是当它们直接在 Management Studio 中运行时,它们显然会保留在内存中。
这意味着我不能在每次调整时重新执行代码,因为它会尝试重新创建表并导致错误。
有时调整代码来避免这种情况很容易,但是当有很多表时,这就有点不切实际了。每次总是将代码复制并粘贴到新的查询窗口中,但这很快就会变得烦人。
有没有什么方法可以简单地从当前会话的内存中清除临时表,以便您可以在每次运行时重新开始?
在 MySQL 中,是否可以CASE在SELECT子句中有两个语句,其中第二个CASE语句依赖于第一个CASE语句?
例如,考虑以下查询:
SELECT CASE WHEN `user`.`id` < 500 THEN 'awesome' ELSE 'lame' END
AS `status`
, CASE WHEN `status` = 'awesome' THEN 'You rock' ELSE 'You stink' END
AS `message`
FROM `user`
Run Code Online (Sandbox Code Playgroud)
基本上,用户 ID 决定状态,然后状态决定消息。
但是,正如您可能已经猜到的,此查询会生成以下错误:
Unknown column 'status'
Run Code Online (Sandbox Code Playgroud)
到目前为止我发现的唯一解决方案是两个生成一个临时表、视图或子查询,然后message由status这个子查询中返回的确定。
有没有办法在不使用临时表、视图或子查询的情况下编写此查询?如果可能的话,我试图避免这些构造以保持查询简单和优化。谢谢!
我有非常大的查询,它从许多表中获取数据并按所有非计算列对它们进行分组。我需要多次重用这个查询,但需要进行其他分组和过滤。在 MSSQL 中,我为此目的使用 CTE 或临时表,但 MySQL 不支持 CTE,并且我不能在同一个查询中多次引用临时表(这是 MySQL 的可悲和不合逻辑的限制)。
SELECT
t1.VideoId,
t1.RegionId,
t1.CountryId,
t1.PerCountryCount,
t2.PerRegionCount
FROM (
SELECT
VideoId,
RegionId,
CountryId,
SUM(PlayCount) PerCountryCount
FROM TrackedData
GROUP BY VideoId, RegionId, CountryId
) t1
INNER JOIN (
SELECT
VideoId,
RegionId,
SUM(PlayCount) PerRegionCount
FROM TrackedData
GROUP BY VideoId, RegionId
) t2
Run Code Online (Sandbox Code Playgroud)
此示例已简化但显示了问题。t1 查询有更详细的数据,我想在 t2 查询中重用它,因为在实际项目中很难在 t1 查询中获取数据(百万行、许多过滤器和分组等)。我想重用这个查询的第二个原因是查询长度。我不想重复有大约 60 行代码的稍微更改的查询。
Oracle 临时表中提交的目的是什么?交易范围:
ON COMMIT DELETE ROWS
Run Code Online (Sandbox Code Playgroud)
当前事务的提交或当前会话中发生的任何提交?
我的 postgresql 数据库中有以下功能:
CREATE OR REPLACE FUNCTION get_unused_part_ids()
RETURNS integer[] AS
$BODY$
DECLARE
part_ids integer ARRAY;
BEGIN
create temporary table tmp_parts
as
select vendor_id, part_number, max(price) as max_price
from refinery_akouo_parts
where retired = false
group by vendor_id, part_number
having min(price) < max(price);
-- do some work etc etc
-- simulate ids being returned
part_ids = '{1,2,3,4}';
return part_ids;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION get_unused_part_ids()
OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)
这会编译,但是当我运行时:
select get_unused_part_ids();
Run Code Online (Sandbox Code Playgroud)
临时表tmp_parts仍然存在。之后我可以做一个选择。请原谅我,因为我已经习惯了 t-sql/MSSQL 的特定功能。MSSQL 不会出现这种情况。我究竟做错了什么?
select t.*
into #temp
from
(
select 'a' as a
union all
select 'b' as a
) as t
select * from #temp
drop table #temp
Run Code Online (Sandbox Code Playgroud)
我通常在SQL服务器上执行此操作,其中我创建一个临时表.语法"into #temp"在DB上创建非物理表,而"into temp"将在DB上创建物理表.
我在MySQL中的问题是转换上面的MSSQL语句.我想要的是创建一个没有在数据库上物理创建的临时表.我们在MySQL中有这个功能吗?
temp-tables ×10
mysql ×4
sql ×4
sql-server ×3
oracle ×2
subquery ×2
case ×1
cursor ×1
function ×1
group-by ×1
inner-join ×1
insert ×1
join ×1
postgresql ×1
sql-function ×1
t-sql ×1
transactions ×1
view ×1