我想在Postgres函数中传递一个表名作为参数.我试过这段代码:
CREATE OR REPLACE FUNCTION some_f(param character varying) RETURNS integer
AS $$
BEGIN
IF EXISTS (select * from quote_ident($1) where quote_ident($1).id=1) THEN
return 1;
END IF;
return 0;
END;
$$ LANGUAGE plpgsql;
select some_f('table_name');
Run Code Online (Sandbox Code Playgroud)
我得到了这个:
ERROR: syntax error at or near "."
LINE 4: ...elect * from quote_ident($1) where quote_ident($1).id=1)...
^
********** Error **********
ERROR: syntax error at or near "."
Run Code Online (Sandbox Code Playgroud)
以下是更改为此时出现的错误select * from quote_ident($1) tab where tab.id=1:
ERROR: column tab.id does not exist
LINE 1: ...T EXISTS …Run Code Online (Sandbox Code Playgroud) 我将所有功能都保存在一个文本文件中'CREATE OR REPLACE FUNCTION somefunction'.因此,如果我添加或更改某些功能,我只需将文件提供给psql.
现在,如果我向现有函数添加或删除参数,它会创建一个具有相同名称的重载,并按照确切的顺序删除所有参数类型中的原始I类型,这是一种单调乏味的操作.
是否有某种通配符,我可以使用DROP具有给定名称的所有函数,所以我可以添加DROP FUNCTION行到我的文件的顶部?
我是数据库开发的新手,所以我对以下示例有些怀疑:
函数f1() - 语言sql
create or replace function f1(istr varchar) returns text as $$
select 'hello! '::varchar || istr;
$$ language sql;
Run Code Online (Sandbox Code Playgroud)
函数f2() - 语言plpgsql
create or replace function f2(istr varchar)
returns text as $$
begin select 'hello! '::varchar || istr; end;
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)
这两个函数都可以像select f1('world')或一样调用select f2('world').
如果我打电话select f1('world')的输出将是:
`hello! world`
Run Code Online (Sandbox Code Playgroud)并输出为select f2('world'):
错误:查询没有结果数据的目的地提示:如果要丢弃SELECT的结果,请改用PERFORM.语境:在SQL语句中PL/pgSQL函数f11(字符变化)第2行 ******错误******
我想知道的差异,在哪些情况下我应该使用language sql或language plpgsql …
我可以使用 PostgreSQL 的带美元引号的字符串常量安全地防止 SQL 注入吗?
我知道处理动态查询的最好方法是使用参数化查询在应用程序层中生成它们,这不是这个问题的内容。所有的业务逻辑都在存储过程中。
我有一个存储过程,它接受参数并生成查询、运行它、格式化结果并将其作为文本块返回。这个函数传递了一个表名、列名和 WHERE 参数。传递给函数的 WHERE 参数来自用户在数据库中输入的数据。我想确保对刺进行消毒,以便构建的查询是安全的。
使用 PostgreSQL 的美元引号字符串常量,我应该能够安全地清理除“ $$ ”之外的所有字符串输入。但是,如果我对 "$" 进行字符串替换以对其进行转义,我应该能够进行安全的字符串比较。
存储过程:
function_name(tablename text, colnames text[], whereparam text)
--Build dynamic query...
Run Code Online (Sandbox Code Playgroud)
函数调用:
SELECT
function_name('tablename', ARRAY['col1', 'col2', 'col3'], 'AND replace(col1, ''$'', ''/$'') = $$' || replace(alt_string_col, '$', '/$') || '$$ ')
FROM alttable
WHERE alt_id = 123;
Run Code Online (Sandbox Code Playgroud)
查询生成:
SELECT col1, col2, col3 FROM tablename WHERE 1=1 AND replace(col1, '$', '/$') = $$un/safe'user /$/$ data;$$
Run Code Online (Sandbox Code Playgroud)
由于我在将 col1 字段与转义的用户数据进行比较之前对其进行了转义,因此即使用户输入“un/safe'user $$ data;” 在字段 alt_string_col 中,双美元符号不会中断查询并且比较通过。
这是在 PostgreSQL …
我有两个这样的表:
CREATE TABLE table1_lang
(
id serial NOT NULL,
lang1 character varying,
lang2 character varying,
...
)
CREATE TABLE table2_lang
(
id serial NOT NULL,
table1_id NOT NULL,
lang1 character varying,
lang2 character varying,
...
)
Run Code Online (Sandbox Code Playgroud)
每个lang列均包含不同语言的名称。我想创建一个从table1_lang返回所选lang的函数(如果存在)。如果该名称在table1_lang中不存在,则该函数应从table2_lang返回该名称。
到目前为止,我已经使用plpgsql中的此函数解决了我的问题:
CREATE OR REPLACE FUNCTION get_name(integer, text)
RETURNS character varying AS
$BODY$
DECLARE
in_id ALIAS FOR $1;
lang ALIAS FOR $2;
table1_name varchar;
table2_name varchar;
BEGIN
IF lang IS NOT NULL AND lang = 'lang1' THEN
SELECT a.lang1 INTO table1_name
FROM table1_lang a …Run Code Online (Sandbox Code Playgroud) 是否可以在 Postgres 中执行以下操作:
SELECT column_name FROM information_schema WHERE table_name = 'somereport' AND data_type = 'integer';
SELECT SUM(coulmn_name[0]),SUM(coulmn_name[1]) ,SUM(coulmn_name[3]) FROM somereport;
Run Code Online (Sandbox Code Playgroud)
换句话说,我需要根据特定条件从表中选择一组列,然后对表中的每一列求和。
我知道我可以在循环中执行此操作,因此我可以独立计算每个列,但显然这需要对从信息模式查询返回的每个列进行查询。例如:
FOR r IN select column_name from information_schema where report_view_name = 'somereport' and data_type = 'integer';
LOOP
SELECT SUM(r.column_name) FROM somereport;
END
Run Code Online (Sandbox Code Playgroud) order byPostgresql 中子句的参数类型是什么?
我遇到了一个非常奇怪的行为(使用 Postgresql 9.5)。即,查询
select * from unnest(array[1,4,3,2]) as x order by 1;
Run Code Online (Sandbox Code Playgroud)
1,2,3,4按预期生产。然而查询
select * from unnest(array[1,4,3,2]) as x order by 1::int;
Run Code Online (Sandbox Code Playgroud)
产生1,4,3,2,这看起来很奇怪。同样,每当我1::int用任何函数(例如greatest(0,1))甚至case运算符替换时,结果都是无序的(与我所期望的相反)。
那么参数应该具有哪种类型order by,以及如何获得预期的行为?
按照此链接中提到的方法,我想ORDER BY动态地传递和排序函数。
ORDER BY工作正常,但我无法通过排序顺序(ASC/ DESC)。
我现在所拥有的:
CREATE OR REPLACE FUNCTION list(_limit integer,_offset integer,sort_by varchar(100), _order varchar(100),_category varchar(100))
RETURNS TABLE(
id INTEGER,
name VARCHAR,
clientname VARCHAR,
totalcount BIGINT
) AS $$
DECLARE empty text := '';
BEGIN
RETURN Query EXECUTE
'SELECT d.id,
d.name,
d.clientname,
count(*) OVER() AS full_count FROM design_list as d
where ($5 = $6 Or d.category Ilike $5)
ORDER BY ' || quote_ident(sort_by) || ' LIMIT $1 offset $2'
USING _limit,_offset,sort_by, …Run Code Online (Sandbox Code Playgroud) postgresql ×8
plpgsql ×6
dynamic-sql ×4
function ×3
sql ×2
sql-order-by ×2
database ×1
identifier ×1
sanitization ×1
sql-drop ×1