postgresql function_name schema_name

本文介绍了一种在PostgreSQL中使用PL/pgSQL语言编写函数,用于解析当前调用堆栈,提取并返回完整的函数名及其所在模式。此外,还提供了获取短函数名和模式名的辅助函数。

CREATE OR REPLACE FUNCTION full_function_name() RETURNS text AS $$
DECLARE
  stack text;
  lines text[];
  arr_len integer = 0;
  index_ integer = 1;
  func_name text;
  schema_name text;
  
BEGIN
  GET DIAGNOSTICS stack = PG_CONTEXT;
  --RAISE NOTICE E'--- Call Stack ---\n%', stack;
  --index_ := strpos(stack, 'PL/pgSQL function ');
  --RAISE NOTICE E'--- index_ = % \n', index_;
  lines = regexp_split_to_array(stack, E'\\n');
  --RAISE NOTICE E'--- lines = % \n', lines;
  arr_len := array_length(lines, 1);
  --RAISE NOTICE E'--- arr_len = % \n', arr_len;
  func_name := lines[arr_len];
  --RAISE NOTICE E'--- func_name = % \n', func_name;
  --index_ := strpos(stack, 'PL/pgSQL function ');
  --RAISE NOTICE '--- index_ = % \n', index_;
  --func_name := substr(stack, index_);
  func_name := substr(func_name, length('PL/pgSQL function ')+1);
  index_ := strpos(func_name, ') line ');
  --RAISE NOTICE '--- index_ = % ', index_;
  func_name := substr(func_name, 1, index_);

  index_ := strpos(func_name, '(');

  schema_name := substr(func_name, 1, index_-1);
  --RAISE NOTICE E'--- schema_name = % \n', schema_name;
  index_ := strpos(schema_name, '.');
  --RAISE NOTICE '--- index_ = % ', index_;
  IF index_ = 0 THEN
    schema_name = current_schema;
    --RAISE NOTICE E'--- schema_name = % \n', schema_name;
    func_name := schema_name||'.'||func_name;
  END IF;
  
  RETURN func_name;
END;
$$ LANGUAGE plpgsql;
 

CREATE OR REPLACE FUNCTION short_function_name() RETURNS text AS $$
DECLARE
  func_name text;
  index_ integer = 1;

BEGIN

  func_name := public.full_function_name();
  index_ := strpos(func_name, '.');
  --RAISE NOTICE '--- index_ = % ', index_;
  func_name := substr(func_name, index_+1);
  --RAISE NOTICE E'--- func_name = % \n', func_name;
  index_ := strpos(func_name, '(');
  --RAISE NOTICE '--- index_ = % ', index_;
  func_name := substr(func_name, 1, index_-1);
  --RAISE NOTICE E'--- func_name = % \n', func_name;
  
  RETURN func_name;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION schema_name() RETURNS text AS $$
DECLARE
  shm_name text;
  index_ integer = 1;

BEGIN

  shm_name := public.full_function_name();
  index_ := strpos(shm_name, '.');
  --RAISE NOTICE '--- index_ = % ', index_;
  shm_name := substr(shm_name, 1, index_-1);
  --RAISE NOTICE E'--- shm_name = % \n', shm_name;
  
  RETURN shm_name;
END;
$$ LANGUAGE plpgsql;
 

mimiciv=# SELECT findattname('mimiciv', 'admissions', 'f'); -- 引用[3] 错误: 函数 findattname(unknown, unknown, unknown) 不存在 第1行SELECT findattname('mimiciv', 'admissions', 'f'); ^ 提示: 没有匹配指定名称和参数类型的函数. 您也许需要增加明确的类型转换. mimiciv=# CREATE OR REPLACE FUNCTION findattname( mimiciv(# schema_name TEXT, mimiciv(# table_name TEXT, mimiciv(# key_type CHAR mimiciv(# ) mimiciv-# RETURNS TEXT mimiciv-# LANGUAGE plpgsql mimiciv-# AS $$ mimiciv$# DECLARE mimiciv$# attribute_name TEXT; mimiciv$# BEGIN mimiciv$# -- 根据键类型查询对应的列名 mimiciv$# IF key_type = 'f' THEN mimiciv$# -- 查询外键约束 mimiciv$# SELECT mimiciv$# kcu.column_name INTO attribute_name mimiciv$# FROM mimiciv$# information_schema.table_constraints AS tc mimiciv$# JOIN mimiciv$# information_schema.key_column_usage AS kcu mimiciv$# ON tc.constraint_name = kcu.constraint_name mimiciv$# AND tc.table_schema = kcu.table_schema mimiciv$# WHERE mimiciv$# tc.constraint_type = 'FOREIGN KEY' mimiciv$# AND tc.table_schema = schema_name mimiciv$# AND tc.table_name = table_name mimiciv$# LIMIT 1; mimiciv$# ELSIF key_type = 'p' THEN mimiciv$# -- 查询主键约束 mimiciv$# SELECT mimiciv$# kcu.column_name INTO attribute_name mimiciv$# FROM mimiciv$# information_schema.table_constraints AS tc mimiciv$# JOIN mimiciv$# information_schema.key_column_usage AS kcu mimiciv$# ON tc.constraint_name = kcu.constraint_name mimiciv$# AND tc.table_schema = kcu.table_schema mimiciv$# WHERE mimiciv$# tc.constraint_type = 'PRIMARY KEY' mimiciv$# AND tc.table_schema = schema_name mimiciv$# AND tc.table_name = table_name mimiciv$# LIMIT 1; mimiciv$# ELSE mimiciv$# RAISE EXCEPTION 'Unsupported key_type: %', key_type; mimiciv$# END IF; mimiciv$# mimiciv$# RETURN attribute_name; mimiciv$# END; mimiciv$# $$; 错误: 创建中没有选择模式 mimiciv=# -- 获取 admissions 表的外键列名 mimiciv=# SELECT findattname('mimiciv', 'admissions', 'f'); 错误: 函数 findattname(unknown, unknown, unknown) 不存在 第1行SELECT findattname('mimiciv', 'admissions', 'f'); ^ 提示: 没有匹配指定名称和参数类型的函数. 您也许需要增加明确的类型转换. mimiciv=# mimiciv=# -- 获取 patients 表的主键列名 mimiciv=# SELECT findattname('mimiciv', 'patients', 'p'); 错误: 函数 findattname(unknown, unknown, unknown) 不存在 第1行SELECT findattname('mimiciv', 'patients', 'p'); ^ 提示: 没有匹配指定名称和参数类型的函数. 您也许需要增加明确的类型转换. mimiciv=#
最新发布
09-25
DROP TABLE IF EXISTS sequence; CREATE TABLE sequence ( name varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, current_value bigint NULL DEFAULT NULL, crement bigint NULL DEFAULT NULL ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic; ALTER TABLE sequence ADD CONSTRAINT pk_name PRIMARY KEY(name); INSERT INTO sequence(name,current_value,crement) select 'pims_seq' as name, concat(cvalue,'2023000000000') as current_value, '1' as crement from t_bims_system_config where ccode='StationNo'; SET FOREIGN_KEY_CHECKS = 1; -- DROP FUNCTION IF EXISTS currval ; CREATE FUNCTION currval(seq_name VARCHAR(30)) RETURNS bigint LANGUAGE SQL DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN DECLARE VALUE bigint; SET VALUE =0; SELECT current_value INTO VALUE FROM sequence WHERE NAME=seq_name; RETURN VALUE; END ; CREATE FUNCTION nextval (seq_name VARCHAR(30)) RETURNS bigint LANGUAGE SQL DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN UPDATE sequence SET current_value = current_value + crement WHERE NAME = seq_name; RETURN currval(seq_name); END; CREATE PROCEDURE db_add_etlId () BEGIN DECLARE s_tablename VARCHAR ( 100 ); DECLARE cur_table_structure CURSOR FOR SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema =(SELECT DATABASE ()) and substr(table_name,1,6) ='t_bims' and table_type='BASE TABLE' AND table_name NOT IN ( SELECT t.table_name FROM ( SELECT table_name, column_name FROM information_schema.COLUMNS where table_schema =(SELECT DATABASE ()) and table_name IN ( SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema =(SELECT DATABASE ()) and substr(table_name,1,6) ='t_bims' and table_type='BASE TABLE') ) t WHERE t.column_name = 'etlId' ); DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s_tablename = NULL; OPEN cur_table_structure; FETCH cur_table_structure INTO s_tablename; WHILE ( s_tablename IS NOT NULL ) DO SET @MyQuery = CONCAT( "alter table `", s_tablename, "` add COLUMN `etlId` bigint;" ); PREPARE MSQL FROM @MyQuery; EXECUTE MSQL; FETCH cur_table_structure INTO s_tablename; END WHILE; CLOSE cur_table_structure; END; CREATE PROCEDURE db_add_etlId_seq () BEGIN DECLARE s_tablename VARCHAR ( 100 ); DECLARE cur_table_structure CURSOR FOR SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema =(SELECT DATABASE ()) and substr(table_name,1,6) ='t_bims' and table_type='BASE TABLE' AND table_name IN ( SELECT t.table_name FROM ( SELECT table_name, column_name FROM information_schema.COLUMNS WHERE table_name IN ( SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema =(SELECT DATABASE ()) and substr(table_name,1,6) ='t_bims' and table_type='BASE TABLE' and table_name<>'t_bims_item_value') ) t WHERE t.column_name = 'etlId' ) order by table_rows desc; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s_tablename = NULL; OPEN cur_table_structure; FETCH cur_table_structure INTO s_tablename; WHILE ( s_tablename IS NOT NULL ) DO SET @MyQuery = CONCAT( "update `", s_tablename, "` set etlId=nextval('pims_seq') where etlId is null;" ); PREPARE MSQL FROM @MyQuery; EXECUTE MSQL; FETCH cur_table_structure INTO s_tablename; END WHILE; CLOSE cur_table_structure; END; 通过这种方式生成了bigint的主键,有没有更方便的方式生成bigint主键,能够数据重新还原后还是得到一样的bigint类型主键。最重要的是保持唯一性。
08-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值