您是否曾经在编写SQL查询和思考中遇到过这种情况,如果我能为此编写快速的PL/SQL功能,那将使这快速简便?但是,不幸的是,您没有任何特权来创建模式中的任何功能。幸运的是,由于Oracle数据库12C,因此有一个答案。
随着Oracle数据库12.1.0.1在2013年发布,Oracle引入了编写匿名PL/SQL声明的能力,作为SQL查询的一部分。这是用WITH
子句完成的,也称为 common Table表达式子句或 cte ,现在可以包含上述匿名PL/SQL声明。
让我们想象一下您有一个table products
,其中包含有关各种卖家产品的信息。这看起来像这样:
CREATE TABLE products (
id NUMBER NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
url VARCHAR(255)
);
INSERT INTO products VALUES (1, 'AirPods Pro (2nd gen)', 'https://www.apple.com/shop/product/MQD83AM/A/airpods-pro');
INSERT INTO products VALUES (2, 'SanDisk - Ultra 512GB USB 3.0', 'https://www.bestbuy.com/site/sandisk-ultra-512gb-usb-3-0-flash-drive-black/6422265.p');
commit;
您想编写一个查询,例如为您提供产品名称,每种产品的出售域和URL。但是您要确保名称和域名的第一个字母始终大写。当然,您可以在纯SQL中执行此操作,但是您对PL/SQL感到满意,并且这些功能很快写入:
get_domain_name函数
FUNCTION get_domain_name
(
p_url VARCHAR2,
p_sub_domain VARCHAR2 DEFAULT 'www.'
)
RETURN VARCHAR2
IS
v_begin_pos BINARY_INTEGER;
v_length BINARY_INTEGER;
BEGIN
v_begin_pos := INSTR(p_url, p_sub_domain) + LENGTH(p_sub_domain);
v_length := INSTR(SUBSTR(p_url, v_begin_pos), '.') - 1;
RETURN SUBSTR(p_url, v_begin_pos, v_length);
END;
大写功能
FUNCTION capitalize (p_string VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN CONCAT(UPPER(SUBSTR(p_string,1,1)), SUBSTR(p_string,2));
END;
使用此新功能,您可以将这两个功能都包装到WITH
子句中,并在您的SQL块中重复使用,甚至多次:
WITH
-- Function to capitalize input string
FUNCTION capitalize
(
p_string VARCHAR2
)
RETURN VARCHAR2
IS
BEGIN
RETURN CONCAT(UPPER(SUBSTR(p_string,1,1)), SUBSTR(p_string,2));
END;
-- Function to retrieve the domain name from a URL
FUNCTION get_domain_name
(
p_url VARCHAR2,
p_sub_domain VARCHAR2 DEFAULT 'www.'
)
RETURN VARCHAR2
IS
v_begin_pos BINARY_INTEGER;
v_length BINARY_INTEGER;
BEGIN
v_begin_pos := INSTR(p_url, p_sub_domain) + LENGTH(p_sub_domain);
v_length := INSTR(SUBSTR(p_url, v_begin_pos), '.') - 1;
RETURN SUBSTR(p_url, v_begin_pos, v_length);
END;
-- SQL statement
SELECT capitalize(name) as name, capitalize(get_domain_name(url)) AS domain_name, url
FROM products;
在数据库中,这只是一个带有常见表表达式的SELECT
语句。您不需要与您相关的用户的模式上的任何写入特权:
SQL> WITH
2 -- Function to capitalize input string
3 FUNCTION capitalize
4 (
5 p_string VARCHAR2
6 )
7 RETURN VARCHAR2
8 IS
9 BEGIN
10 RETURN CONCAT(UPPER(SUBSTR(p_string,1,1)), SUBSTR(p_string,2));
11 END;
12 -- Function to retrieve the domain name from a URL
13 FUNCTION get_domain_name
14 (
15 p_url VARCHAR2,
16 p_sub_domain VARCHAR2 DEFAULT 'www.'
17 )
18 RETURN VARCHAR2
19 IS
20 v_begin_pos BINARY_INTEGER;
21 v_length BINARY_INTEGER;
22 BEGIN
23 v_begin_pos := INSTR(p_url, p_sub_domain) + LENGTH(p_sub_domain);
24 v_length := INSTR(SUBSTR(p_url, v_begin_pos), '.') - 1;
25 RETURN SUBSTR(p_url, v_begin_pos, v_length);
26 END;
27 -- SQL statement
28 SELECT capitalize(name) as name, capitalize(get_domain_name(url)) AS domain_name, url
29 FROM products;
30 /
NAME DOMAIN_NAME URL
________________________________ ______________ _______________________________________________________________________________________
AirPods Pro (2nd gen) Apple https://www.apple.com/shop/product/MQD83AM/A/airpods-pro
SanDisk - Ultra 512GB USB 3.0 Bestbuy https://www.bestbuy.com/site/sandisk-ultra-512gb-usb-3-0-flash-drive-black/6422265.p