有时我的存储过程看起来像
create procedure handle_data
@fk int,
@value varchar(10)
as
begin
if exists (select * from my_table where id = @fk)
begin
update my_table
set value = @value
where id = @fk
end
else
begin
insert into my_table (fk, value)
select @fk, @value
end
end
Run Code Online (Sandbox Code Playgroud)
调用此存储过程的应用程序设计可能存在错误。
我应该避免制作执行相同存储过程和方法来插入新数据并更新旧数据的应用程序吗?
有没有更好的方法来以一种方法实现更新或插入数据?
我正在使用 SQL Server 2005 / 2008。
最近我正在阅读这篇博文:http : //blogs.msdn.com/b/sqlazure/archive/2010/05/05/10007304.aspx
其中包含此部分:
选择聚集索引
有几种选择聚集索引的策略;最简单和最好的方法之一是添加另一列数据类型为 datetime 的列,并将该列用于聚集索引。以下是您需要做的:
将列添加为数据类型日期时间
我通常称之为日期
将默认值设置为 GetDate()。
使其非空。
在向您插入数据之前,先在其上创建聚集索引。
我的问题是这是否会为日期创建两个相同的值?如果使用并行性,这个答案会改变吗?(假设从未指定值,总是来自 GetDate())
我相信我的假设是正确的,因为添加了幕后唯一标识符,这无关紧要,对吧?但反正我很感兴趣。
我是从 SQL2008R2 的角度提出问题,但如果答案对 7.0 以上的任何 SQL Server 版本有所不同,我会很感兴趣。
我知道这是您可以在本网站上找到的最简单的问题,但我无法在互联网上找到答案。
如何检查触发器是否由INSERT或触发DELETE?
CREATE TRIGGER [dbo].[TestTrigger]
On [dbo].[Table1]
AFTER INSERT, DELETE
AS
--if save
--do some work
--else if delete
--do some work other work
Run Code Online (Sandbox Code Playgroud)
如果是insert,我想做一些工作,如果是delete ,我想做一些其他工作。
请提供相同的代码片段。
CREATE TABLE `dummy` (
`a` TINYINT(4) NOT NULL
) ENGINE=MyISAM;
Run Code Online (Sandbox Code Playgroud)
1 错误值
INSERT INTO `dummy` (`a`) VALUES (NULL);
/* SQL Fehler (1048): Column 'a' cannot be null */
/* Nothing is stored! */
Run Code Online (Sandbox Code Playgroud)
2个错误的值
INSERT INTO `dummy` (`a`) VALUES (NULL), (NULL);
/* Affected rows: 2 Gefundene Zeilen: 0 Warnungen: 2 Dauer von Abfrage: ... sec. */
SHOW WARNINGS LIMIT 5; /* Not sure where this comes from! Maybe HeidiSQL? */
/* Two entries are stored! */
Run Code Online (Sandbox Code Playgroud)
为什么 MySQL 会在单值查询中引发错误,而在具有两个值的第二个查询中却没有?
它与 …
我正在使用 Postgres 9.5。我为我的三个表创建了一个 INSERT 转储文件。为了避免出现外键错误,我将以下内容添加到文件的顶部和底部(“...”是所有插入的位置)...
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
SET search_path = public, pg_catalog;
ALTER TABLE addresses DISABLE TRIGGER ALL;
ALTER TABLE table1 DISABLE TRIGGER ALL;
ALTER TABLE table2 DISABLE TRIGGER ALL;
…
ALTER TABLE addresses ENABLE TRIGGER ALL;
ALTER TABLE table1 ENABLE TRIGGER ALL;
ALTER TABLE table2 ENABLE TRIGGER ALL;
Run Code Online (Sandbox Code Playgroud)
但是,即使我运行这个文件,我也会收到类似的错误
ERROR: insert or update …Run Code Online (Sandbox Code Playgroud) 我正在尝试以一种可重现的方式用一些测试数据填充数据库。
假设(一个过于简化的示例)三个基表:name、city、job 和两个关系表:name-city 和 name-job。我需要在三个基表中的每一个中创建一个条目,并使用上述条目在两个关系表中创建条目。
我已经拥有了一种使用一系列with查询在 3 个基表中创建条目并将值插入到一个关系表中的方法。
with x as
(INSERT INTO "public"."name" VALUES(DEFAULT) RETURNING "id"),
y as
(INSERT INTO "public"."job" VALUES(DEFAULT) RETURNING "id"),
z as
(INSERT INTO "public"."city" VALUES(DEFAULT) RETURNING "id")
INSERT INTO "public"."name-job"("name", "job")
select x.id, y.id from x,y;
Run Code Online (Sandbox Code Playgroud)
我真的想添加第二个插入语句
INSERT INTO "public"."name-city"("name", "city")
select x.id, z.id from x,z;
Run Code Online (Sandbox Code Playgroud)
第一次插入后,但不知道如何。我曾尝试用逗号分隔两个插入语句,并将它们括在括号中,然后用逗号分隔它们,以及其他一些方法,但没有任何效果。
使用带有第二个插入的全新语句并不完全是一种选择,因为我需要使用相同的 x、y、z 值。鉴于我缺乏专业知识/经验,我完全有可能遗漏了一些明显的东西......所以任何关于我如何做到这一点的想法,理想情况下,没有高度复杂的工具,将是最受欢迎的。
FWIW,我正在使用 Postgres (10.x)
我创建了一个查询,我想将结果插入到另一个表中。它将每天作为作业运行,导入的数据仍将保留在结果集中。如果数据已存在于目标表中,我不希望导入数据。查询如下所示:
WITH cteUniquePages
(
CorrelationID,
Title,
URL,
HitDate,
TotalVisitsOnDate,
DontUseThisDate)
AS
(
SELECT DISTINCT
CorrelationID,
Title,
URL,
HitDate,
COUNT(HitDate) OVER (PARTITION BY URL, HitDate) 'TotalVisitsOnDate',
CAST(LogTime AS date) 'DontUseThisDate'
FROM
(SELECT
CorrelationId,
UserLogin,
LogTime,
Title,
CONCAT(
(CASE
WHEN WebUrl <> '' THEN CONCAT(ServerUrl,'/') ELSE ServerUrl END),
WebUrl,DocumentPath) 'URL',
CONCAT(
CASE
WHEN (LEN(DATEPART(day,LogTime)))=1 THEN CONCAT('0',DATEPART(day,LogTime)) END,
CASE
WHEN (LEN(DATEPART(day,LogTime)))=2 THEN (DATEPART(day,LogTime)) END,'-',
CASE
WHEN (LEN(DATEPART(month,LogTime)))=1 THEN CONCAT('0',DATEPART(month,LogTime)) END,
CASE
WHEN (LEN(DATEPART(month,LogTime)))=2 THEN (DATEPART(month,LogTime)) END,
'-', DATEPART(year,LogTime)) 'HitDate'
FROM WSS_Logging.dbo.RequestUsage
WHERE UserLogin …Run Code Online (Sandbox Code Playgroud) 我有这个生成随机字符串的语句:
SELECT string_agg (substr('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', ceil (random() * 62)::integer, 1), '')
FROM generate_series(1, 20);
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何在函数内实现此功能,该函数会将上述语句的值自动分配给url_prefix创建新记录时命名的字段(on INSERT's)?
如果以下循环查询在循环过程中被终止,是所有插入还是仅当前一个回滚?
DECLARE @LoopId INT = 1;
WHILE (@LoopId < 100)
BEGIN
INSERT INTO Table2
SELECT Field1
FROM Table1
WHERE ForeignKeyField = @LoopId
SET @LoopId = @LoopId + 1;
END
Run Code Online (Sandbox Code Playgroud) 我有这个表,用于生成带有结果的第二个表:
INSERT INTO payment_transactions_daily_facts (count, volume, date, year, month, week, day, transaction_type, contract_id, merchant_id, terminal_id, status, card_brand, currency)
SELECT
COUNT(*) count,
SUM(amount) volume,
DATE(created_at) date,
YEAR(created_at) year,
MONTH(created_at) month,
WEEK(created_at) week,
DAY(created_at) day,
type transaction_type,
contract_id, merchant_id, terminal_id,
status, card_brand, currency
FROM payment_transactions
WHERE created_at BETWEEN '2018-11-11' AND '2018-11-14'
GROUP by date, contract_id, merchant_id, terminal_id, transaction_type, status, card_brand, currency
Run Code Online (Sandbox Code Playgroud)
但是我需要在插入之前删除旧数据。有没有办法用一个 SQL 先删除从某个日期开始的表数据,然后再插入一个新的?
insert ×10
sql-server ×4
postgresql ×3
t-sql ×3
mysql ×2
dump ×1
errors ×1
foreign-key ×1
functions ×1
index ×1
mariadb ×1
mariadb-10.3 ×1
mysql-5.6 ×1
random ×1
rollback ×1
subquery ×1
transaction ×1
trigger ×1
update ×1
warning ×1