我正在尝试使用Postgres进行自我管理的分区表设置.这一切都围绕着这个功能,但我似乎无法让Postgres接受我的表名.自我管理分区表触发器功能的任何想法或示例?
我目前的职能:
DECLARE
day integer;
year integer;
tablename text;
startdate text;
enddate text;
BEGIN
day:=date_part('doy',to_timestamp(NEW.date));
year:=date_part('year',to_timestamp(NEW.date));
tablename:='pings_'||year||'_'||day||'_'||NEW.id;
-- RAISE EXCEPTION 'tablename=%',tablename;
PERFORM 'tablename' FROM pg_tables WHERE 'schemaname'=tablename;
-- RAISE EXCEPTION 'found=%',FOUND;
IF FOUND <> TRUE THEN
startdate:=date_part('year',to_timestamp(NEW.date))||'-'||date_part('month',to_timestamp(NEW.date))||'-'||date_part('day',to_timestamp(NEW.date));
enddate:=startdate::timestamp + INTERVAL '1 day';
EXECUTE 'CREATE TABLE $1 (
CHECK ( date >= DATE $2 AND date < DATE $3 )
) INHERITS (pings)' USING quote_ident(tablename),startdate,enddate;
END IF;
EXECUTE 'INSERT INTO $1 VALUES (NEW.*)' USING quote_ident(tablename);
RETURN NULL;
END;
Run Code Online (Sandbox Code Playgroud)
我希望它自动创建一个名为的表,pings_YEAR_DOY_ID
但它始终失败: …
给定以下架构:
create table account_type_a (
id SERIAL UNIQUE PRIMARY KEY,
some_column VARCHAR
);
create table account_type_b (
id SERIAL UNIQUE PRIMARY KEY,
some_other_column VARCHAR
);
create view account_type_a view AS select * from account_type_a;
create view account_type_b view AS select * from account_type_b;
Run Code Online (Sandbox Code Playgroud)
我尝试在plpgsql中创建一个通用的触发器函数,它可以更新视图:
create trigger trUpdate instead of UPDATE on account_view_type_a
for each row execute procedure updateAccount();
create trigger trUpdate instead of UPDATE on account_view_type_a
for each row execute procedure updateAccount();
Run Code Online (Sandbox Code Playgroud)
我的不成功的努力是:
create function updateAccount() returns trigger …
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写plpgsql以下形式的函数(注意这是一个简化版本):
CREATE FUNCTION check_valid(tablename regclass) RETURNS boolean AS $$
DECLARE valid_row tablename%ROWTYPE;
BEGIN
EXECUTE format('SELECT * FROM %s', tablename) into valid_row;
IF valid_row IS NULL THEN
RETURN QUERY SELECT false;
ELSIF valid_row.is_valid = false;
RETURN QUERY SELECT false;
ELSIF valid_row.hit_count > valid_row.hit_limit;
RETURN QUERY SELECT false;
ELSE
RETURN QUERY SELECT true;
END IF;
END
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
失败的部分是DECLARE
线.如何根据变量表名声明类型?或许我需要以某种方式施展它?
类似的DECLARE mytable%ROWTYPE;
工作正常,但如果我使用变量名称,如tablename%ROWTYPE
:
ERROR: relation "tablename" does not exist
我已经找到了我要在Oracle和SQL Server上解决的问题的解决方案(我认为),但是似乎无法将其转换为Postgres解决方案。我正在使用Postgres 9.3.6。
这个想法是为了生成用于分析目的的有关表内容的“元数据”。这只能通过让每一列都运行查询来找出(例如...)最小/最大/计数值等来完成(AFAIK)。为了使过程自动化,最好让数据库生成查询,然后执行查询。
使用示例salesdata
表,我可以使用以下代码段为每列生成一个选择查询,并返回min()值:
SELECT 'SELECT min('||column_name||') as minval_'||column_name||' from salesdata '
FROM information_schema.columns
WHERE table_name = 'salesdata'
Run Code Online (Sandbox Code Playgroud)
优点是,无论列数如何,数据库都会生成代码。现在,我想到了无数个地方来存储这些查询,这些查询可以是某种变量,也可以是表列,其想法是执行这些查询。我想将生成的查询存储在变量中,然后使用EXECUTE
(或EXECUTE IMMEDIATE
)语句执行它们,这是此处采用的方法(请参见右窗格),但是Postgres不会让我在函数外部声明变量,因此我一直在抓挠我对如何将它们组合在一起,无论是什至是遵循的方向,也许还有更简单的东西。
您有任何指点吗,由于其他问题,我目前正在尝试类似的方法,但不知道我是否朝着正确的方向前进:
CREATE OR REPLACE FUNCTION foo()
RETURNS void AS
$$
DECLARE
dyn_sql text;
BEGIN
dyn_sql := SELECT 'SELECT min('||column_name||') from salesdata'
FROM information_schema.columns
WHERE table_name = 'salesdata';
execute dyn_sql
END
$$ LANGUAGE PLPGSQL;
Run Code Online (Sandbox Code Playgroud) postgresql dynamic-sql plpgsql aggregate-functions dynamic-queries
我有几个 bash 脚本来查询 mysql 数据库并获取表名,我使用以下命令:
mysql -NBA --user=$DB_user --password=$DB_pass --database=$DB_name -e 'show tables'
Run Code Online (Sandbox Code Playgroud)
使用 -NBA 参数,我过滤结果并得到如下结果:
categories
colections
colors
files
Run Code Online (Sandbox Code Playgroud)
在 postgreSQL 和 psql 中,我试图实现相同的格式,我正在阅读文档并使用以下参数:
psql --username=$DB_user -W --host=$HOST --dbname=$DB_name -Atc '\dt'
Run Code Online (Sandbox Code Playgroud)
这是我能得到的最好的
public|categories|table|user
public|colections|table|dbuser
public|colors|table|dbuser
public|files|table|dbuser
Run Code Online (Sandbox Code Playgroud)
在最坏的情况下,我需要解析它以仅获取表的名称,但如果有人知道实现我想要的目标的方法,我会很高兴。
在我的数据库中有许多文本列,其中值是空字符串 ( ''
)。空字符串需要设置为NULL
. 我不知道这个数据库中的确切模式、表和列,或者我想编写一个可以重用的通用解决方案。
我将如何编写查询/函数来查找所有模式中所有表中的所有文本列,并将所有带有空字符串 ( ''
) 的列更新为NULL
?
对于物理表,我一直在使用以下 SQL:
select column_name, data_type, character_maximum_length
from INFORMATION_SCHEMA.COLUMNS
where table_name = 'a_table_name'
Run Code Online (Sandbox Code Playgroud)
我发现这不适用于视图。有没有办法通过运行 SQL 命令(而不是通过 psql)来获取视图的模式。
在 Firebird 中,我有以下代码来检查表是否存在:
SET TERM ^ ;
EXECUTE BLOCK AS
BEGIN
IF (NOT EXISTS(SELECT 1 FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = 'TESTE')) THEN
BEGIN
EXECUTE STATEMENT
'CREATE TABLE TESTE( ' ||
'CDTESTE VARCHAR(7) NOT NULL, ' ||
'FATURA VARCHAR(7)); ';
EXECUTE STATEMENT 'ALTER TABLE TESTE ADD CONSTRAINT PK_TESTE PRIMARY KEY (CDTESTE)';
END
END^
SET TERM ; ^
Run Code Online (Sandbox Code Playgroud)
我如何在 Postgres 中使用匿名块来做到这一点?对不起我的英语。
postgresql ×8
plpgsql ×5
sql ×4
dynamic-sql ×3
bash ×1
inheritance ×1
mysql ×1
psql ×1
triggers ×1