是否可以将字段值扩展为比较运算符?像这样的东西:
create table math (
value1 int,
value2 int,
operator text
);
insert into math values(1,2,'>=');
select * from math where value1 operator value2;
PS:我知道可以通过 解决这个用例case when
,但想知道是否有替代解决方案。
是否可以将字段值扩展为比较运算符?像这样的东西:
create table math (
value1 int,
value2 int,
operator text
);
insert into math values(1,2,'>=');
select * from math where value1 operator value2;
PS:我知道可以通过 解决这个用例case when
,但想知道是否有替代解决方案。
我有一个接收参数的过程,并根据这些参数进行动态声明。该语句始终返回一个数值。如何返回该值,或将其传递给变量?
例如以下:
DECLARE VAR1_INPUT INT;
DECLARE SQLSTRING VARCHAR(5000);
DECLARE OUTPUTVAR INT;
SET VAR1_INPUT = 5;
SET SQLSTRING = 'select next value into :OUTPUTVAR for MYSCHEMA.MYSEQUENCE_'||CAST(VAR1_INPUT AS VARCHAR(25))||' from sysibm.sysdummy1';
EXECUTE IMMEDIATE SQLSTRING;
我想我可以使用游标,但这将执行很多并且需要轻量级,我宁愿避免使用游标。并且不要专注于上面的无意义的动态 SQL,这只是一个示例。:)
编辑:原始问题从表中选择一个值作为问题。答案与此相符,因此我将其标记为正确答案。后来我意识到序列的工作方式不同,所以我编辑了这个问题。这部分我一直想不通。
我得到的数据是
ID | 日期 | cnt |
---|---|---|
1 | '2021-11-26' | 1 |
1 | '2021-11-25' | 1 |
1 | '2021-11-24' | 1 |
1 | '2021-11-23' | 1 |
我想要的结果是
ID | 从日期 | 迄今为止 | cnt |
---|---|---|---|
1 | '2021-11-23' | '2021-11-24' | 2 |
1 | '2021-11-23' | '2021-11-25' | 3 |
1 | '2021-11-23' | '2021-11-26' | 4 |
1 | '2021-11-24' | '2021-11-25' | 2 |
1 | '2021-11-24' | '2021-11-26' | 3 |
1 | '2021-11-25' | '2021-11-26' | 2 |
有没有办法从数据中的日期列生成这些日期(from_date,to_date)?
我需要从日期的迭代中使用循环吗?
我还能想到什么来接近结果?
提前致谢
假设使用下面的函数,我需要调试EXECUTE
语句中执行的内容。USING
(现实中提供动态变量的长动态语句)
CREATE OR REPLACE FUNCTION fn() RETURNS integer LANGUAGE 'plpgsql'
AS $$
BEGIN
EXECUTE $x$
SELECT $1, $2, $3
$x$ USING 1, '2020-01-01'::date, NULL::date;
RETURN 0;
END;
$$;
似乎在这种情况下,您能做的最好的事情就是取回字符串SELECT $1, $2, $3
。有没有办法打印/提高SELECT 1, '2020-01-01'::date, NULL::date
?
(我会想象类似的东西format('%1$s', 'xyz')
?)
我有函数命名
Schema.func_date(date,varchar)
我想这样做(我在 Store proc 中使用以下语句)
Execute 'Select *, ID as Main_Id, ' ||
'schema.func_date(quote_literal('2020-02-20'),quote_literal('ST')), '||
'from main_table'
传递单引号字符串时出现无效操作错误。如何在执行语句中完美传递单引号字符串?
让我们使用 CASE 子句进行日常查询,以便向您展示问题,看看当新的认证出现时我们必须如何更改查询:
select count(*) as "certCount",
CASE
when c.id = 1 then 'AWS Cloud Practitioner'
when c.id = 2 then 'AWS Alexa Skill Builder'
when c.id = 3 then 'AWS Solution Architect Associate'
when c.id = 4 then 'AWS Developer Associate'
when c.id = 5 then 'AWS SysOps Associate'
when c.id = 6 then 'AWS Solution Architect Professional'
when c.id = 7 then 'AWS DevOps Professional'
when c.id = 8 then 'AWS Security'
when c.id = 9 then 'AWS Networking'
when c.id = 10 then 'AWS Big Data'
when c.id = 11 then 'AWS Machine Learning'
ELSE 'N/A'
END AS name
from certification c
inner join qualification q on c.id = q.certificationid
group by q.certificationid, c.id
当然,我们可以生成 SQL 并以 Ad-Hoc 方式执行它。这是我过去所做的,尽管我想知道是否有另一种方式,比如某种加入方式可以避免 CASE WHENs?
下面的模式和示例数据,它在 PostGres 中,但我也对 Oracle、SQLServer 等的动态案例语句感兴趣:
CREATE TABLE certification (
id serial NOT NULL,
officialcertname text NOT NULL,
"name" text NOT NULL,
vendorid int4 NOT NULL DEFAULT 1,
isdeleted bool NOT NULL DEFAULT false,
CONSTRAINT certification_pkey PRIMARY KEY (id)
);
CREATE TABLE qualification (
id serial NOT NULL,
employeeid int4 NOT NULL,
certificationid int4 NOT NULL,
date_attained timestamptz NULL,
date_expiry timestamptz NULL,
certurl text NULL,
verified bool NOT NULL DEFAULT false,
created_by text NOT NULL,
created_date timestamptz NOT NULL,
modified_by text NULL,
modified_date timestamptz NULL,
CONSTRAINT qualification_pkey PRIMARY KEY (id)
);
INSERT INTO certification (officialcertname,"name",vendorid,isdeleted) VALUES
('AWS Certified Cloud Practitioner (CLF)','AWS Cloud Practitioner',1,false)
,('AWS Certified Alexa Skill Builder','AWS Alexa Skill Builder',1,false)
,('AWS Certified Solutions Architect - Associate (SAA)','AWS Solution Architect Associate',1,false)
,('AWS Certified Developer - Associate (DVA)','AWS Developer Associate',1,false)
,('AWS Certified SysOps Administrator - Associate (SOA)','AWS SysOps Associate',1,false)
,('AWS Certified Solutions Architect - Professional (SAP)','AWS Solution Architect Professional',1,false)
,('AWS Certified DevOps Engineer - Professional (DOP)','AWS DevOps Professional',1,false)
,('AWS Certified Security - Specialty (SCS)','AWS Security',1,false)
,('AWS Certified Networking - Specialty (SNS)','AWS Networking',1,false)
,('AWS Certified Big Data - Specialty','AWS Big Data',1,false)
;
varchar(max)
ASE中的 SQL Server 数据类型等价物是什么?
ASE 我指的是过去被称为 Sybase ASE 的东西,它现在归 SAP 所有。
我正在尝试执行一段超过 8,000 个字符的动态构造的 T-SQL。
如果我用 声明一个变量varchar(max)
,ASE 会阻塞:
关键字“max”附近的语法不正确。
我的下一个想法是尝试text
数据类型。可惜:
您为包含“立即执行”命令字符串的变量指定了不正确的数据类型。
一个最小的、完整的、可验证的例子:
DECLARE @cmd varchar(max) --change this to varchar(4000) and it works
SET @cmd = 'SELECT 1;'
EXEC (@cmd);
GO
将变量声明更改为text
或任何适合您的目的。我需要执行一个可能有 50,000 个字符长的动态命令。
或者,我可以使用游标,但我不熟悉游标在 ASE 上的工作方式。
请注意,在 SQL Anywhere 中,您可以将 varchar(max) 数据类型的等价物定义为declare @cmd long varchar;
,但这在 ASE 中不起作用。
我有 4 个相互关联的表。
表位置:
CREATE TABLE `location` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `location` (`id`, `name`) VALUES
(1, 'Dallas'),
(2, 'Boston'),
(3, 'Houston');
表项:
CREATE TABLE `item` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`brand` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `item` (`id`, `brand`) VALUES
(1, 'Nissan Almera M/T 2009-2015'),
(2, 'Toyota Corolla A/T 2005-2012'),
(3, 'Nissan Terra A/T 2010-2017'),
(4, 'Suzuki Esteem M/T 1980-1990'),
(5, 'Toyota Fortuner A/T 2014-2020');
表 item_in:
CREATE TABLE `item_in` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`location_id` bigint(20) UNSIGNED NOT NULL,
`item_id` bigint(20) UNSIGNED NOT NULL,
`quantity` int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `item_in` (`id`, `location_id`, `item_id`, `quantity`) VALUES
(1, 1, 1, 1000),
(2, 1, 2, 500),
(3, 2, 2, 200),
(4, 2, 2, 300),
(5, 3, 3, 300),
(6, 1, 3, 800),
(7, 3, 5, 300),
(8, 3, 4, 400);
表 item_out:
CREATE TABLE `item_out` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`location_id` bigint(20) UNSIGNED NOT NULL,
`item_id` bigint(20) UNSIGNED NOT NULL,
`quantity` int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `item_out` (`id`, `location_id`, `item_id`, `quantity`) VALUES
(1, 1, 2, 20),
(2, 1, 1, 25),
(3, 2, 2, 25),
(4, 3, 3, 25),
(5, 3, 5, 10),
(6, 3, 4, 15),
(7, 1, 1, 200),
(8, 2, 2, 50);
使用动态 SQL,我能够根据它们的位置和项目(item_in 数量减去 item_out 数量)获取每个项目的单独剩余数量,并将位置名称作为列。(见下面的代码):
SET @sql = NULL, @sql1 = NULL, @sql2 = NULL;
SELECT GROUP_CONCAT( DISTINCT
CONCAT('SUM(CASE WHEN `location_id` = ''',`location_id`, ''' THEN quantity END) AS ',`name`))
INTO @sql1
FROM item_in
JOIN location on location.id = item_in.location_id;
SELECT GROUP_CONCAT( DISTINCT
CONCAT('SUM(CASE WHEN `location_id` = ''',`location_id`, ''' THEN quantity END) AS ',`name`))
INTO @sql2
FROM item_out
JOIN location on location.id = item_out.location_id;
SET @sql = CONCAT('SELECT item.brand AS Item, IFNULL(item_in.Dallas, 0) - IFNULL(item_out.Dallas, 0) AS Dallas, IFNULL(item_in.Boston, 0) - IFNULL(item_out.Boston, 0) AS Boston, IFNULL(item_in.Houston, 0) - IFNULL(item_out.Houston, 0) AS Houston FROM item LEFT JOIN (SELECT item_in.item_id, ', @sql1, ' FROM item_in
GROUP BY item_in.item_id) AS item_in ON item.id = item_in.item_id LEFT JOIN (SELECT item_out.item_id, ', @sql2, ' FROM item_out
GROUP BY item_out.item_id) AS item_out ON item.id = item_out.item_id');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
结果:
Item | Dallas | Boston | Houston
Nissan Almera M/T 2009-2015 775 0 0
Toyota Corolla A/T 2005-2012 480 425 0
Nissan Terra A/T 2010-2017 800 0 275
Suzuki Esteem M/T 1980-1990 0 0 385
Toyota Fortuner A/T 2014-2020 0 0 290
我的问题是,我该如何更改代码以便动态显示位置名称列,而不是在查询中手动对其进行硬编码,因为用户可以随时添加新位置?如果有人可以查看我的代码,我将非常感谢您的帮助。我遇到麻烦的唯一部分是如何不对这些行进行硬编码并动态执行它们:
IFNULL(item_in.Dallas, 0) - IFNULL(item_out.Dallas, 0) AS Dallas, IFNULL(item_in.Boston, 0) - IFNULL(item_out.Boston, 0) AS Boston, IFNULL(item_in.Houston, 0) - IFNULL(item_out.Houston, 0) AS Houston
我正在尝试使用动态 sql (MS SQL Server 13.0.5426) 创建一个临时表。这是一个简化的例子:
使用直接 SQL 可以:
DROP TABLE #tmp_ts; -- will error, but ignored on the first execution
SELECT CURRENT_TIMESTAMP ts INTO #tmp_ts;
SELECT * FROM #tmp_ts;
通过动态 SQL 创建它不起作用。
DROP TABLE #tmp_ts; -- drop from previous test.
EXEC sp_executesql N'SELECT CURRENT_TIMESTAMP ts INTO #tmp_ts';
SELECT * FROM #tmp_ts;
输出:
(受影响的 1 行)
消息 208,级别 16,状态 0,第 63 行无效的对象名称“#tmp_ts”。
我的解决方法是不使用临时表,但我很好奇是否有人知道为什么这不起作用。
谢谢!