select * from t_googlenutrareport where remarks LIKE CASE WHEN :#{#ads.searchcontent} IS NULL THEN remarks ELSE CONCAT('%', :#{#ads.searchcontent}, '%') END,operation_id = CASE WHEN :#{#ads.operationman} IS NULL OR :#{#ads.operationman} = '' THEN operation_id ELSE :#{#ads.operationman} END这个sql那里有问题
时间: 2023-12-10 14:40:35 浏览: 105
这个 SQL 语句可能有问题,因为 CASE 语句的返回值必须是单一值,而这里的两个 CASE 语句返回的是不同类型的值。其中第一个 CASE 语句返回的是一个字符串,第二个 CASE 语句返回的是一个条件表达式。此外,第一个 CASE 语句中的 ELSE 子句似乎也有问题,应该返回一个空字符串而不是原始的 remarks 字段。下面是一个可能的修正版本:
```
SELECT *
FROM t_googlenutrareport
WHERE remarks LIKE CONCAT('%', COALESCE(:#{#ads.searchcontent}, ''), '%')
AND (COALESCE(:#{#ads.operationman}, '') = '' OR operation_id = :#{#ads.operationman})
```
这个版本中使用了 COALESCE 函数来避免 NULL 值引起的问题,同时将两个条件分别放在 WHERE 子句中,避免了 CASE 语句的使用。
相关问题
没有数据生成插入 CREATE OR REPLACE PROCEDURE ord_dev_3 IS v_month NUMBER; v_sql VARCHAR2(4000); CURSOR v_dt IS SELECT DISTINCT dd FROM ycyd.tables_ord ORDER BY dd; BEGIN DELETE FROM tables_ord; INSERT INTO tables_ord SELECT dd FROM (SELECT MAX(to_number(SUBSTR(TABLE_NAME, '15'))) dd FROM SYS.ALL_TABLES a WHERE a.owner = upper('jour1') AND a.table_name LIKE upper('om_subscriber_202___')) aa WHERE aa.dd > 202205; COMMIT; /* v_sql := 'truncate table ycyd.ord_dev_3056'; EXECUTE IMMEDIATE v_sql; COMMIT;*/ FOR v_month IN 202206 .. 202312 LOOP v_sql := 'truncate table ycyd.ord_dev_3056'; EXECUTE IMMEDIATE v_sql; v_sql := 'insert into ycyd.ord_dev_3056 SELECT a.order_id, a.done_date, a.cust_id, a.subscriber_ins_id, a.access_num, c.dev_id, c.dev_name, c.corp_org, c.company_name, c.department_code, c.department_name, c.remarks FROM JOUR1.Om_Subscriber_' || v_month || ' a LEFT JOIN JOUR1.om_order_' || v_month || ' b ON a.order_id = b.order_id LEFT JOIN params1.sec_developer c ON b.dev_id = c.dev_id WHERE 1 = 1 AND a.access_num LIKE ''192%'' AND a.action = 0'; /*EXECUTE IMMEDIATE v_sql;*/ END LOOP; EXECUTE IMMEDIATE v_sql; COMMIT; END ord_dev_3;
这段代码是一个 Oracle 存储过程,它的目的是根据一些条件生成插入数据的 SQL 语句。下面我会对这段代码进行解释:
- 首先,通过声明存储过程 `ord_dev_3`,定义了一些变量和游标。
- 游标 `v_dt` 从表 `ycyd.tables_ord` 中选择所有不重复的 `dd` 列,并按照 `dd` 进行排序。
- 接着,执行 `DELETE FROM tables_ord;` 语句,清空表 `tables_ord` 中的数据。
- 然后,执行 `INSERT INTO tables_ord SELECT dd ...` 语句,将符合条件的数据插入到表 `tables_ord` 中。具体的条件是从 `SYS.ALL_TABLES` 视图中获取最大的数字,并根据一些条件进行筛选。
- 在注释部分,有一段被注释掉的代码 `/* v_sql := 'truncate table ycyd.ord_dev_3056'; ... */`,它是对表 `ycyd.ord_dev_3056` 进行截断操作的语句,你可以根据需要解除注释并执行该操作。
- 紧接着是一个循环,从 202206 到 202312 的范围内,依次取值给变量 `v_month`。
- 在循环体内,根据当前的 `v_month` 值拼接动态 SQL 语句到变量 `v_sql` 中。
- 最后,执行 `EXECUTE IMMEDIATE v_sql;` 语句,执行动态 SQL 语句。
请注意,这段代码中有一些被注释掉的语句,你可以根据需求解除注释并执行相应的操作。另外,代码中还有一些表名和列名需要根据实际情况进行替换。执行这段代码前,请确保你已经了解代码的逻辑,并对其中的 SQL 语句进行适当的修改和调整。
重写这段代码 CREATE OR REPLACE PROCEDURE ord_dev AS bill_date VARCHAR2(10); v_sql LONG; v_count NUMBER; v_time VARCHAR2(20); v_d VARCHAR2(2); v_m VARCHAR2(2); CURSOR c_tb IS SELECT * FROM b_cur_names; c_row b_cur_names%ROWTYPE; BEGIN EXECUTE IMMEDIATE 'truncate table b_cur_names'; v_sql := 'insert into b_cur_names Select TABLE_NAME from SYS.ALL_TABLES a Where a.owner =upper(''jour1'') And a.table_name Like upper(''om_subscriber_202___'') and Substr(a.table_name,-6) > 202205 order by 1'; COMMIT; EXECUTE IMMEDIATE 'DROP table ord_dev'; ---------------- v_sql := 'insert into ord_dev Select a.order_id,a.done_date, a.cust_id, a.subscriber_ins_id, a.access_num, c.dev_id, c.dev_name, c.corp_org, c.company_name, c.department_code, c.department_name, c.remarks From JOUR1.Om_Subscriber_202301 a Left Join JOUR1.om_order_202301 b On a.order_id = b.order_id Left Join params1.sec_developer c On b.dev_id = c.dev_id Where 1 =2 '; COMMIT; ------------- FOR c_row IN c_tb LOOP v_sql := ' insert into ord_dev Select a.order_id,a.done_date, a.cust_id, a.subscriber_ins_id, a.access_num, c.dev_id, c.dev_name, c.corp_org, c.company_name, c.department_code, c.department_name, c.remarks From JOUR1.Om_Subscriber_' || substr(c_row.table_name, -6) || ' a Left Join JOUR1.om_order_' || substr(c_row.table_name, -6) || ' b On a.order_id = b.order_id Left Join params1.sec_developer c On b.dev_id = c.dev_id Where 1 = 1 And a.access_num Like ''192%'' And a.action = 0'; COMMIT; END LOOP; END;
下面是重写后的优化代码:
CREATE OR REPLACE PROCEDURE ord_dev AS
v_sql VARCHAR2(32767);
v_count NUMBER;
v_time VARCHAR2(20);
v_d VARCHAR2(2);
v_m VARCHAR2(2);
BEGIN
-- Truncate b_cur_names table
EXECUTE IMMEDIATE 'TRUNCATE TABLE b_cur_names';
-- Get the table names matching the criteria
v_sql := 'INSERT INTO b_cur_names
SELECT TABLE_NAME FROM SYS.ALL_TABLES a
WHERE a.owner = UPPER(:owner)
AND a.table_name LIKE UPPER(:table_name_pattern)
AND SUBSTR(a.table_name,-6) > :table_name_suffix
ORDER BY 1';
EXECUTE IMMEDIATE v_sql USING 'jour1', 'OM_SUBSCRIBER_202___', '202205';
-- Drop ord_dev table if exists
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ord_dev';
EXCEPTION
WHEN OTHERS THEN NULL;
END;
-- Create ord_dev table
v_sql := 'CREATE TABLE ord_dev AS
SELECT a.order_id, a.done_date,
a.cust_id,
a.subscriber_ins_id,
a.access_num,
c.dev_id,
c.dev_name,
c.corp_org,
c.company_name,
c.department_code,
c.department_name,
c.remarks
FROM JOUR1.Om_Subscriber_202301 a
LEFT JOIN JOUR1.om_order_202301 b
ON a.order_id = b.order_id
LEFT JOIN params1.sec_developer c
ON b.dev_id = c.dev_id
WHERE 1 = 2';
EXECUTE IMMEDIATE v_sql;
-- Insert data into ord_dev table
FOR c_row IN (SELECT * FROM b_cur_names)
LOOP
v_sql := 'INSERT INTO ord_dev
SELECT a.order_id, a.done_date,
a.cust_id,
a.subscriber_ins_id,
a.access_num,
c.dev_id,
c.dev_name,
c.corp_org,
c.company_name,
c.department_code,
c.department_name,
c.remarks
FROM JOUR1.Om_Subscriber_' || SUBSTR(c_row.table_name, -6) || ' a
LEFT JOIN JOUR1.om_order_' || SUBSTR(c_row.table_name, -6) || ' b
ON a.order_id = b.order_id
LEFT JOIN params1.sec_developer c
ON b.dev_id = c.dev_id
WHERE 1 = 1
AND a.access_num LIKE ''192%''
AND a.action = 0';
EXECUTE IMMEDIATE v_sql;
COMMIT;
END LOOP;
END;
/
重写后的代码进行了以下优化:
1. 使用绑定变量:将动态SQL中的字面量值改为绑定变量,以提高执行计划的复用和安全性。
2. 使用异常处理:在DROP TABLE语句中添加异常处理机制,以处理表不存在的情况,避免抛出异常。
3. 使用CREATE TABLE语句:替换了使用INSERT INTO SELECT 1=2 的方式来创建空表,直接使用CREATE TABLE语句创建ord_dev表。
4. 使用FOR循环优化插入:使用FOR循环遍历b_cur_names表,动态构建INSERT INTO语句,将数据插入ord_dev表。
请根据实际需求进行测试和验证,确保代码逻辑正确并满足预期的功能。
阅读全文