相关疑难解决方法(0)

选择随机行PostgreSQL的最佳方法

我想在PostgreSQL中随机选择一行,我试过这个:

select * from table where random() < 0.01;
Run Code Online (Sandbox Code Playgroud)

但其他一些人推荐这个:

select * from table order by random() limit 1000;
Run Code Online (Sandbox Code Playgroud)

我有一个非常大的表,有5亿行,我希望它快.

哪种方法更好?有什么区别?选择随机行的最佳方法是什么?

sql random postgresql performance

311
推荐指数
9
解决办法
19万
查看次数

截断Postgres数据库中的所有表

我经常需要在重建之前删除PostgreSQL数据库中的所有数据.我将如何直接在SQL中执行此操作?

目前我已经设法提出一个SQL语句,它返回我需要执行的所有命令:

SELECT 'TRUNCATE TABLE ' ||  tablename || ';' FROM pg_tables WHERE tableowner='MYUSER';
Run Code Online (Sandbox Code Playgroud)

但是,一旦拥有它们,我就无法以编程方式执行它们.

postgresql truncate dynamic-sql plpgsql database-table

142
推荐指数
8
解决办法
13万
查看次数

如果在PostgreSQL上不存在列,如何添加列?

问题很简单.如何将列添加x到表中y,但仅当x列不存在时?我在这里找到了解决方法,如何检查列是否存在.

SELECT column_name 
FROM information_schema.columns 
WHERE table_name='x' and column_name='y';
Run Code Online (Sandbox Code Playgroud)

postgresql postgresql-9.1

128
推荐指数
5
解决办法
10万
查看次数

如何在PostgreSQL中进行大型非阻塞更新?

我想在PostgreSQL中对表进行大量更新,但我不需要在整个操作中维护事务完整性,因为我知道我正在更改的列不会被写入或读取更新.我想知道psql控制台中是否有一种简单的方法可以更快地完成这些类型的操作.

例如,假设我有一个名为"orders"的表,有3500万行,我想这样做:

UPDATE orders SET status = null;
Run Code Online (Sandbox Code Playgroud)

为避免被转移到offtopic讨论,让我们假设3500万列的所有状态值当前都设置为相同(非空)值,从而使索引无用.

此语句的问题是需要很长时间才能生效(仅因为锁定),并且所有更改的行都将被锁定,直到整个更新完成.此更新可能需要5个小时,而类似

UPDATE orders SET status = null WHERE (order_id > 0 and order_id < 1000000);
Run Code Online (Sandbox Code Playgroud)

可能需要1分钟.超过3500万行,执行上述操作并将其分成35块只需要35分钟,节省了4小时25分钟.

我可以用脚本进一步分解它(在这里使用伪代码):

for (i = 0 to 3500) {
  db_operation ("UPDATE orders SET status = null
                 WHERE (order_id >" + (i*1000)"
             + " AND order_id <" + ((i+1)*1000) " +  ")");
}
Run Code Online (Sandbox Code Playgroud)

此操作可能仅在几分钟内完成,而不是35分钟.

所以这归结为我真正的要求.我不想写一个怪异的脚本来分解操作,每次我想做这样一个大的一次性更新.有没有办法在SQL中完成我想要的东西?

postgresql dblink transactions plpgsql sql-update

61
推荐指数
3
解决办法
3万
查看次数

重构PL/pgSQL函数以返回各种SELECT查询的输出

我写了一个函数,输出一个SELECT以文本形式组成的PostgreSQL 查询.现在我不想再输出文本,但实际上SELECT对数据库运行生成的语句并返回结果 - 就像查询本身一样.

到目前为止我所拥有的:

CREATE OR REPLACE FUNCTION data_of(integer)
  RETURNS text AS
$BODY$
DECLARE
   sensors varchar(100);   -- holds list of column names
   type    varchar(100);   -- holds name of table
   result  text;           -- holds SQL query
       -- declare more variables

BEGIN
      -- do some crazy stuff

      result := 'SELECT\r\nDatahora,' || sensors ||
      '\r\n\r\nFROM\r\n' || type ||
      '\r\n\r\nWHERE\r\id=' || $1 ||'\r\n\r\nORDER BY Datahora;';

      RETURN result;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION data_of(integer) OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)

sensors …

sql database postgresql dynamic-sql plpgsql

32
推荐指数
1
解决办法
2万
查看次数

在触发器函数中使用动态表名INSERT

我不确定如何实现以下内容:

CREATE OR REPLACE FUNCTION fnJobQueueBEFORE() RETURNS trigger AS $$
    DECLARE
        shadowname varchar := TG_TABLE_NAME || 'shadow';
    BEGIN
        INSERT INTO shadowname VALUES(OLD.*);
        RETURN OLD;
    END;
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

即将值插入到具有动态生成名称的表中.
执行上面的代码会产生:

ERROR:  relation "shadowname" does not exist
LINE 1: INSERT INTO shadowname VALUES(OLD.*)
Run Code Online (Sandbox Code Playgroud)

它似乎表明变量不会作为表名扩展/允许.我在Postgres手册中没有发现这个.

我已经尝试过EXECUTE这样的事情:

  EXECUTE 'INSERT INTO ' || quote_ident(shadowname) || ' VALUES ' || OLD.*;
Run Code Online (Sandbox Code Playgroud)

但没有运气:

ERROR:  syntax error at or near ","
LINE 1: INSERT INTO personenshadow VALUES (1,sven,,,)
Run Code Online (Sandbox Code Playgroud)

RECORD类型似乎失去了:OLD.*似乎被转换为字符串,并得到的重新解析,导致各种各样的类型的问题(例如NULL值). …

postgresql triggers dynamic-sql plpgsql

31
推荐指数
1
解决办法
2万
查看次数

我该怎么做:USE @databaseName

 DECLARE @DatabaseName NVARCHAR(max); SET @DatabaseName = 'MainDb'
 USE @DatabaseName
Run Code Online (Sandbox Code Playgroud)

不行.怎么做?

t-sql sql-server

23
推荐指数
3
解决办法
5万
查看次数

PostgreSQL:创建表,如果不存在AS

我正在使用PostgreSQL并且是一个SQL初学者.我正在尝试从查询中创建一个表,如果我运行:

CREATE TABLE table_name AS
   (....query...)
Run Code Online (Sandbox Code Playgroud)

它工作得很好.但是如果我添加'if not exists'并运行:

CREATE TABLE IF NOT EXISTS table_name AS
   (....query...)
Run Code Online (Sandbox Code Playgroud)

使用完全相同的查询,我得到:

ERROR: syntax error at or near "as"
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

sql postgresql create-table

20
推荐指数
2
解决办法
3万
查看次数

在Postgres 9.0+中使用PL/pgSQL循环表

我想遍历所有表来计算每个表中的行数.以下查询给我一个错误:

DO $$
DECLARE
    tables CURSOR FOR
        SELECT tablename FROM pg_tables
        WHERE tablename NOT LIKE 'pg_%'
        ORDER BY tablename;
    tablename varchar(100);
    nbRow int;
BEGIN
    FOR tablename IN tables LOOP
        EXECUTE 'SELECT count(*) FROM ' || tablename INTO nbRow;
        -- Do something with nbRow
    END LOOP;
END$$;
Run Code Online (Sandbox Code Playgroud)

错误:

ERROR:  syntax error at or near ")"
LINE 1: SELECT count(*) FROM (sql_features)
                                          ^
QUERY:  SELECT count(*) FROM (sql_features)
CONTEXT:  PL/pgSQL function inline_code_block line 8 at EXECUTE statement
Run Code Online (Sandbox Code Playgroud)

sql_features是我的数据库中的表名.我已经尝试使用quote_ident()但无济于事.

postgresql variables loops plpgsql tablename

17
推荐指数
2
解决办法
6万
查看次数

为PostgreSQL中的记录变量动态传递列名

使用PostgreSQL,第一条记录的表中的列值存储在记录变量中.例如:让变量为:recordvar

recordvar.columnname
Run Code Online (Sandbox Code Playgroud)

给出指定列名的值.我将columname在变量中定义:

var := columnname
Run Code Online (Sandbox Code Playgroud)

在地方columnname,如果我与变量如更换recordvar.var,这是行不通的.

请让我知道如何处理这种情况.以下是示例代码:

CREATE OR REPLACE FUNCTION getrowdata(id numeric, table_name character varying)
RETURNS SETOF void AS
$BODY$ 
DECLARE

srowdata record;
reqfield character varying;
value numeric;


BEGIN

RAISE NOTICE 'id: %',id; 
reqfield:= 'columnname';

EXECUTE 'select * from datas.'||table_name||' WHERE id = '||id into srowdata;

RAISE NOTICE 'srowdata: %',srowdata; 

RAISE NOTICE 'srowdatadata.columnname: %',srowdata.columnname;

value:= srowdata.reqfield;

RAISE NOTICE 'value: %',value;


END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
Run Code Online (Sandbox Code Playgroud)

postgresql types dynamic-sql plpgsql hstore

17
推荐指数
1
解决办法
2万
查看次数