我有一个带有外键和一个布尔值的表(以及一些其他与此无关的列),如下所示:
CREATE TABLE myTable
(
someKey integer,
someBool boolean
);
insert into myTable values (1, 't'),(1, 't'),(2, 'f'),(2, 't');
Run Code Online (Sandbox Code Playgroud)
每个someKey可以有0个或更多条目.对于任何给定的someKey,我需要知道a)所有条目是否为真,或b)任何条目都是假的(基本上是AND).
我想出了以下功能:
CREATE FUNCTION do_and(int4) RETURNS boolean AS
$func$
declare
rec record;
retVal boolean = 't'; -- necessary, or true is returned as null (it's weird)
begin
if not exists (select someKey from myTable where someKey = $1) then
return null; -- and because we had to initialise retVal, if no rows are found true would be returned
end if;
for …Run Code Online (Sandbox Code Playgroud) 我是PostgreSQL的新手,并且正在使用PGAdmin中的查询工具.我正在尝试运行使用变量的pgsql查询,但我似乎无法正确使用语法.
这是一个给出语法错误的示例查询:
DECLARE
num INTEGER;
BEGIN
num := 3;
PRINT num;
END;
Run Code Online (Sandbox Code Playgroud)
更新:
好的,让我试试解释一下.我来自SQL服务器背景.在管理工作室中,我可以打开一个查询窗口并使用(T)-SQL查询.
例如,我可以写这样的东西:
DECLARE @num INT
SET @num = 3
SELECT @num
Run Code Online (Sandbox Code Playgroud)
我知道这是一个愚蠢的例子,但我只是试图声明一个变量并用它做一些事情.我正在尝试熟悉PL/PGSQL.
再次更新:再次
是我.我正在尝试下面的脚本并获得"[ERROR] 7.0-2:语法错误,意外字符".这是否适用于PGAdmin?
DECLARE
num INTEGER;
BEGIN
num := 3;
RAISE NOTICE '%', num;
END;
Run Code Online (Sandbox Code Playgroud) 我的触发器有问题.在插入新行时,它将检查文章是否未售出.我可以在软件中做到这一点,但我认为这对DB来说更好.
-- Create function
CREATE OR REPLACE FUNCTION checkSold() RETURNS TRIGGER AS $checkSold$
BEGIN
SELECT offer_id FROM offer WHERE offer_id = NEW.offer_id AND date_sale IS NULL;
IF NOT FOUND THEN
RAISE EXCEPTION 'The Offer is Sold!';
END IF;
RETURN NEW;
END;
$checkSold$ LANGUAGE plpgsql;
-- Create trigger
Drop TRIGGER checkSold ON tag_map;
CREATE TRIGGER checkSold BEFORE INSERT ON tag_map FOR EACH ROW EXECUTE PROCEDURE checkSold();
INSERT INTO tag_map (tag_id,offer_id) VALUES (824,80);
Run Code Online (Sandbox Code Playgroud)
这是插入后的错误.
[WARNING ] INSERT INTO tag_map (tag_id,offer_id) VALUES (824,80) …Run Code Online (Sandbox Code Playgroud) 我们正在重新设计postgres中的表模式.它曾经有两个表partner和advertiser名称的链接表,partner_advertiser因为我们假设合作伙伴和广告商之间有很多关系.进行更改,使得advertiser只有一个partner,因此partner将具有一个可能的关系advertiser.
如何在不丢失先前信息的情况下进行更改?必须使用链接器表数据来填充新架构设计的映射.这是我的初始代码:
BEGIN
FOR r IN SELECT partnerid, advertiserid from partner_advertiser
LOOP
NEXT r;
UPDATE advertiser SET partnerid = r.partnerid WHERE id = r.advertiserid
END LOOP;
END
Run Code Online (Sandbox Code Playgroud)
顺便说一下,我自己没有做过任何pg/plsql.所以,如果我有任何基本步骤,请给我一个提醒.
在postgresql plpgsql中,
create function f1( p_i int ) returns table( c1 int ) as $$
begin
-- wish to exit, do not wish to return anything
if p_i < 0 then
-- cannot RETURN - since can only return record!
end if;
-- continue processing
return query select c2 from t1 where c1 = p_i;
...
end;
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)
根据doc,断开函数的唯一方法是RETURN.但这里的RETURN需要RETURN QUERY或RETURN NEXT - 似乎没有办法简单地退出该功能.
CREATE OR REPLACE FUNCTION msgfailerror() RETURNS trigger AS
' BEGIN
IF NEW.noces< new.first_column THEN
RAISE EXCEPTION 'cannot have a negative salary';
END IF;
return new;
END' LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)
触发
create trigger msgfail before insert on first for each row
execute procedure msgfailerror()
Run Code Online (Sandbox Code Playgroud)
给出错误:
"不能"或其附近的语法错误第5行:RAISE EXCEPTION'不能有负面...
对于每个行字段,我几乎有一个验证.我希望触发器在插入完成时检查所有验证,然后一次性提高错误日志.我应该在加薪通知中使用加薪例外吗?
例如:
Insert into first (first_column, noces,dob) values ('4545','75','545')
Run Code Online (Sandbox Code Playgroud)
我正在检查noces是否小于first_column,对于同一行我想检查dob> 80以及first_column是否为整数并且为所有验证引发错误.提前致谢
我想创建一个sql查询(或plpgsql),md5()所有给定的行,无论类型如何.但是,在下面,如果一个为null,则哈希值为null:
UPDATE thetable
SET hash = md5(accountid || accounttype || createdby || editedby);
Run Code Online (Sandbox Code Playgroud)
我稍后使用哈希比较唯一性,因此空哈希不适用于此用例.
问题是它处理连接空值的方式.例如:
thedatabase=# SELECT accountid || accounttype || createdby || editedby
FROM thetable LIMIT 5;
1Type113225
<NULL>
2Type11751222
3Type10651010
4Type10651
Run Code Online (Sandbox Code Playgroud)
如果我知道类型,我可以使用coalesce或CASE语句; 但是,我有很多表,我不会提前知道每一列的类型.
我正在开发一个项目,我在PostgreSQL环境中担任数据库设计师/管理员.领导者决定将Rails用于应用程序逻辑并招募一名Rails程序员.
Rails程序员说他通常会编写所有应用程序代码,并且不喜欢让某人通过他存储过程而导致缺乏控制,并且他从未在rails中完成过.
数据库使用了很多继承/ EERM,因此存储过程和触发器将使他的工作变得更容易,除了使用procs的性能优势.
我有四个问题:
1)如何从没有返回值的Rails调用pl/pgSQL存储过程
2)如何使用单个返回值(1行/ 1列)从Rails调用pl/pgSQL存储过程
3)如何从Rails调用pl/pgSQL存储过程,其中1行多列返回值.
4)如何使用OUT参数从Rails调用pl/pgSQL存储过程?
谢谢!
ruby stored-procedures ruby-on-rails plpgsql rails-postgresql
我在PL/Proxy中设置了一个存储过程来进行查询,然后收回一些RECORD.
在PL /代理中:
CREATE OR REPLACE FUNCTION query_autocomplete(q text, i_id bigint)
RETURNS SETOF RECORD AS $$
CLUSTER 'autocompletecluster';
RUN ON i_id;
$$ LANGUAGE plproxy;
Run Code Online (Sandbox Code Playgroud)
在每个分区中:
CREATE OR REPLACE FUNCTION query_autocomplete(q text, i_id bigint)
RETURNS SETOF RECORD AS $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN EXECUTE q
LOOP
RETURN NEXT rec;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
正如您可能猜到的那样,这是在PGSQL中命名为'autocompletecluster'的定义的SERVER.我发送的查询字符串如下:
$sql = "SELECT * FROM autocomplete WHERE member_id = :memberId";
$query = $this->db->prepare("SELECT query_autocomplete('{$sql}',1234");
Run Code Online (Sandbox Code Playgroud)
它返回以下内容:
SQLSTATE[XX000]: Internal error: 7 ERROR: PL/Proxy …Run Code Online (Sandbox Code Playgroud) 我试着在下面的代码示例中模拟我的问题.在下面的代码中,我正在执行select * from test一个过程.我们知道,我们必须使用perform关键字.这非常有效:
perform * from test;
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试将该简单查询重写为CTE,我无法使其正常工作.我收到语法错误.
with test_as_cte as(select * from test) perform * from test_as_cte;
Run Code Online (Sandbox Code Playgroud)
这可能吗?什么是正确的语法?我尝试了几种替代方案并通过文档,但到目前为止没有任何成功.
(请注意,这只是解释我的问题的一个例子.我知道查询没有任何意义.)
create table test
(
key int primary key
);
create function test() returns trigger as
$$
begin
raise notice 'hello there';
-- this does work
perform * from test;
-- this doesn't work
with test_as_cte as(select * from test) perform * from test_as_cte;
return new;
end;
$$
language plpgsql;
create trigger test after insert on …Run Code Online (Sandbox Code Playgroud)