如何动态地从 plpgsql 函数中的记录中寻址一列?
在以下代码段中,我可以访问一个变量entity.colname,该变量包含应在 IF 控制结构中检查的列。我正在研究如何foobar用entity.colname. 这在 plpgsql 中可能吗?
IF NEW.foobar IS NULL THEN
RAISE EXCEPTION '% cannot be null', foobar;
END IF;
Run Code Online (Sandbox Code Playgroud)
这是可以但行不通的事情。
IF NEW.entity.colname IS NULL THEN
RAISE EXCEPTION '% cannot be null', entity.colname;
END IF;
Run Code Online (Sandbox Code Playgroud)
上面的例子只是为了说明我想要实现的目标,不要判断功能。:)
我正在使用 PostgreSQL 9.1。
考虑一种情况,需要执行一堆本质上相同的操作,唯一的变量是某个对象的名称。
在我的情况下,我需要删除一些模式,所有的形式ceu_shard_test_merge_*,以使用 shell globbing 术语。所以,从概念上讲,这可以写成
DROP SCHEMA ceu_shard_test_merge_* CASCADE;
Run Code Online (Sandbox Code Playgroud)
以类比 Unix shell。
当然这个命令不起作用,那么如何用一个命令来做到这一点呢?我的理解是,这不能以可移植的方式完成。我使用的是 PostgreSQL 8.4,但用于更新 PG 版本的方法也很好。
如果解决方案有一个试运行或虚拟选项,那就太好了,这样人们就可以在实际运行之前看到将要运行哪些命令。也许只是打印命令的一种方法?
此外,指示如何处理比给出的示例更通用的模式会很好。
我正在尝试从旧表创建新表结构的更新,但不使用函数。我正在尝试为其创建一个脚本。旧表是这样的:
旧表 ( OldTable)
| 姓名 | 可乐 | 列b | 列_c |
|---|---|---|---|
| ABC | 0 | 无效的 | 1 |
| DEF | 1 | 1 | 1 |
| 生长激素指数 | 无效的 | 1 | 0 |
并且,新表:
Users:
| ID | 姓名 |
|---|---|
| 1 | ABC |
| 2 | DEF |
| 3 | 生长激素指数 |
Rules:
| ID | 规则名称 |
|---|---|
| 1 | 可乐 |
| 2 | 列b |
| 3 | 列_c |
| 4 | 寒冷的 |
UserRule
| ID_USER | ID_规则 |
|---|
因此,我需要使用 TableMix 上的选择结果填充表 UserRules,其中用户名等于表 User 上的用户名,并且 TableMix 中列 <col_name> 的值等于 1。(select <col_name>来自 OldTable,其中 OldTable.name = Users.name)。嗯,我正在尝试这个:
DO $$
DECLARE rules CURSOR FOR SELECT column_name FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = …Run Code Online (Sandbox Code Playgroud) 就像我的第一个问题中详细介绍的那样,我有一个Postgres 9.1数据库,其中有多个表,这些表具有完全相同的列名,它们仅在列值上有所不同:
tbl_log_a
tbl_log_b
tbl_log_c
...
Run Code Online (Sandbox Code Playgroud)
26 个表(从 a 到 z)。trfn_tbl_log_%letter%每个表都有一个触发器,它调用名为(from ato )的触发器函数z,该函数执行完全相同的操作:
CREATE OR REPLACE FUNCTION trfn_tbl_log_a_timetypespan()
RETURNS trigger AS
$BODY$
DECLARE
v_timetype character varying;
v_timestmp_timetype timestamp without time zone;
v_timetypespan_resume interval;
v_stmtserial real;
v_sumtimetypespan_fnname interval;
BEGIN
IF NEW.timetype = 'lap' THEN
SELECT timetype, timestmp, timetypespan FROM tbl_log_a WHERE fnname = NEW.fnname AND (timetype = 'start' OR timetype = 'resume') ORDER BY stmtserial DESC LIMIT 1 INTO v_timetype, v_timestmp_timetype, v_timetypespan_resume; …Run Code Online (Sandbox Code Playgroud) 我正在 Postgres 中开发一个函数,旨在为查询的每个记录恢复一组函数中包含的检查结果的值。只有这些函数之一会返回正确的值。这些函数有一个公共前缀“fn_condition_”,并接收一个“my_table”类型的对象作为参数。
由于进行检查的函数数量未知,我决定查阅 Postgres 目录,从表中pg_catalog.pg_proc搜索带有前缀“fn_condition_”的函数并使用EXECUTE.
我的问题是将参数传递给EXECUTE.
create or replace function test_conditions()
returns void as
$$
declare
v_record my_table%rowtype;
v_function pg_proc%rowtype;
begin
set search_path = 'pg_catalog';
for v_record in (select * from my_table where id in (1,2,3)) loop
for v_function in (
SELECT p.proname
FROM pg_namespace n
JOIN pg_proc p
ON p.pronamespace = n.oid
WHERE n.nspname = 'operacional'
and p.proname like ('fn_condition\\_%')
order by p.proname)
loop
-- execute 'select ' || v_function.proname || '(' …Run Code Online (Sandbox Code Playgroud) 当我在 MY_Database 上运行以下查询时
select * from sys.sysfiles
Run Code Online (Sandbox Code Playgroud)
我得到以下结果:
但是当我运行一个动态查询来获取可用空间的百分比时,我得到:
消息 8115,级别 16,状态 7,第 93 行 将数字转换为数据类型数字的算术溢出错误。
DECLARE @command NVARCHAR(MAX)
SELECT @command = 'SELECT db_name() as db_name,
CAST(S.size/128.0 - CAST(FILEPROPERTY(S.name, ' + '''' +
'SpaceUsed' + '''' + ' ) AS int)/128.0 AS int) AS FreeSpaceMB
,CAST(100 * (CAST (((S.size/128.0 -CAST(FILEPROPERTY(S.name,
' + '''' + 'SpaceUsed' + '''' + ' ) AS int)/128.0)/(S.size/128.0))
AS decimal(5,2))) AS varchar(8)) + ' + '''' + '''' + ' AS FreeSpacePct
FROM sys.sysfiles S'
exec …Run Code Online (Sandbox Code Playgroud) sql-server filegroups dynamic-sql database-size sql-server-2014
我得到了要在 ( BEFORE UPDATE) 触发器中设置的列的名称,我想将其设置为该OLD值并忽略传入的任何内容。我尝试了以下操作:
CREATE OR REPLACE FUNCTION prevent_column_update() RETURNS TRIGGER AS $$
DECLARE
col TEXT := TG_ARGV[0];
BEGIN
EXECUTE format('SELECT ($1).%I INTO ($2).%I', col, col) USING OLD, NEW;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
并使用如下:
CREATE TRIGGER request_protect_date_price_value
BEFORE UPDATE OF date_price ON requests
FOR EACH ROW EXECUTE PROCEDURE prevent_column_update('date_price');
Run Code Online (Sandbox Code Playgroud)
但是当更新它失败时:
ERROR: syntax error at or near "("
LINE 1: SELECT ($1).date_price INTO ($2).date_price
^
QUERY: SELECT ($1).date_price INTO ($2).date_price
Run Code Online (Sandbox Code Playgroud) 我有几个结构完全相同的表,我需要更新所有表中的值。
为此,我尝试构建以下脚本:
DO
$do$
DECLARE
i pg_tables%rowtype;
BEGIN
FOR i IN SELECT * FROM pg_catalog.pg_tables where schemaname like 'public' and tablename like '%_knex_migrations'
LOOP
UPDATE i.tablename SET name = replace(name, '.js', '.ts');
END LOOP;
END
$do$;
Run Code Online (Sandbox Code Playgroud)
我可以看到它i.tablename具有正确的值(我插入到 tmp 表中进行检查),但更新失败。
name: error
length: 223
severity: ERROR
code: 42P01
internalPosition: 8
internalQuery: UPDATE i."tablename" SET name = replace(name, '.js', '.ts')
where: PL/pgSQL function inline_code_block line 7 at SQL statement
file: parse_relation.c
line: 965
routine: parserOpenTable
Run Code Online (Sandbox Code Playgroud)
只是声明i.tablename上的插件UPDATE不起作用。 …
我目前正在处理一堆服务器,它们有不同的数据库邮件配置。
我可以看到每个服务器的数据库邮件配置。
我使用以下脚本:
--==========================================================
-- getting the Database Mail Configuration
-- Marcelo Miorelli
-- 1-April-2014
--==========================================================
select @@servername
--SQLSALON1\STOCKALLOCATION
-- http://dba.stackexchange.com/questions/47058/how-can-i-see-the-current-database-mail-configuration
EXEC msdb.dbo.sysmail_help_configure_sp;
EXEC msdb.dbo.sysmail_help_account_sp;
EXEC msdb.dbo.sysmail_help_profile_sp;
EXEC msdb.dbo.sysmail_help_profileaccount_sp;
EXEC msdb.dbo.sysmail_help_principalprofile_sp;
EXEC msdb.dbo.sysmail_help_account_sp
Run Code Online (Sandbox Code Playgroud)
实际上,msdb.dbo.sysmail_help_account_sp在这方面,程序是我最喜欢的。
现在我想通过电子邮件发送前一天的备份历史记录(仅完整备份和差异备份),我需要找出每个服务器的配置文件名称。
我想通过将上述过程的内容保存到临时表或表变量中来完成此操作,并在我拥有所需的所有数据并且即将通过电子邮件发送给他们时从中查询信息。
对于那些程序,特别是 sysmail_help_account_sp,我该如何做到这一点?
我特别需要找出profile name. 我已经用于DBA下面的脚本。
这是我用来生成电子邮件内容的脚本:
--=====================================================================================================================
-- sql server backups report in HTML format to be emailed
--http://dba.stackexchange.com/questions/81432/how-do-i-use-powershell-to-get-a-sql-server-backup-status
--marcelo miorelli
--19-nov-2014
--=====================================================================================================================
DECLARE @Body VARCHAR(MAX),
@TableHead VARCHAR(MAX),
@TableTail VARCHAR(MAX)
SET NoCount ON ; …Run Code Online (Sandbox Code Playgroud) 假设我正在制作一个 IRC 机器人,除了应该存储在数据库中的所有其他东西之外,我想记录机器人所在的每个通道中的所有消息。
我已经有一个channels与列的表id,channel_name以及其他一些信息。
对于记录每条消息,对我来说最有意义的是messages_channelname为每个通道创建一个表,并在其中存储消息以及与其关联的任何其他信息。
但是,这引发了一个问题 - 表的名称现在与通道的名称分离id(尽管我可以通过将表名称设置为 来缓解这种情况messages_channelid)。
我觉得这里的最佳实践,而不是最有意义的做法,是拥有一个messages包含来自所有频道的消息的主表,列channel_id,id和message,id每个频道的消息索引在哪里。但是随后我会(毫无根据地)担心表格大小和可能的搜索速度。
解决这个问题的最佳方法是什么?
dynamic-sql ×10
postgresql ×7
plpgsql ×5
sql-server ×2
trigger ×2
backup ×1
catalogs ×1
filegroups ×1
scripting ×1
select ×1
update ×1