PostgresSQL 常用操作方法
1、后台生成XML作为参数然后数据库解析获取数据
var idList = ids.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
var root = new XElement("xml");
if (idList.Length > 0)
{
foreach (var id in idList)
{
var rightX = new XElement("item");
rightX.SetAttributeValue("id", id);
root.Add(rightX);
}
}
string projectXml = root.ToString().Replace("<xml>", "<xml xmlns=\"xmlns\">");
pgsql中的pl/pgsql 使用不是很方便,后面加了xmlns属性是用来转换表格获取节点,官方文档是这样的。。
CREATE OR REPLACE FUNCTION public.fn_SchoolBotProjectSet(Schoolid TEXT,projectxml TEXT)
RETURNS numeric
LANGUAGE plpgsql
AS $function$
DECLARE
_schoolid integer := schoolid;
_projectxml XML := projectxml;
r_count integer :=0;
BEGIN
IF _projectxml IS DOCUMENT THEN
-- -- 解析xml保存入表变量:项目
CREATE TEMPORARY TABLE Project(
Id CHAR(12)
);
WITH xmldata(data) AS (VALUES (_projectxml::xml))
INSERT INTO Project
SELECT xmltable.*
FROM XMLTABLE(XMLNAMESPACES('xmlns' AS x),
'/x:xml/x:item'
PASSING (SELECT data FROM xmldata)
COLUMNS id text PATH '@id');
IF NOT EXISTS (SELECT 1 FROM md_UserBotProject AS pro WHERE pro.SchoolId=_schoolid) THEN
INSERT INTO md_UserBotProject
SELECT Project.Id, _schoolid,NULL
FROM Project
LEFT OUTER JOIN md_UserBotProject ON (md_UserBotProject.ProjectId = Project.Id);
-- WHERE md_UserBotProject.ProjectId IS NULL;
GET DIAGNOSTICS r_count := row_count;
ELSE
DELETE FROM md_UserBotProject AS pro WHERE pro.schoolid=_schoolid;
INSERT INTO md_UserBotProject
SELECT Project.Id, _schoolid,NULL
FROM Project
LEFT OUTER JOIN md_UserBotProject ON (md_UserBotProject.ProjectId = Project.Id);
GET DIAGNOSTICS r_count := row_count; --获取操作行数
END IF;
-- DROP TABLE Project; --最后需要DROP临时表
IF r_count >0 THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
ELSE
RETURN -1;
END IF;
END;
$function$
;
XML参数格式
<xml xmlns="xmlns">
<item id="5f303b8c0001" />
<item id="5f303b980002" />
</xml>
2、操作后返回自动增长列的值(增删改都可以,houseid为自动增长列)
DELETE FROM md_SchoolHouse WHERE houseid = 2 RETURNING houseid;
--md_bathmachine表名 machineid列名
_MachineId := (SELECT currval('md_bathmachine_machineid_seq'::regclass) AS id);
3、清空数据并初始化自动增长列1(student为表名)
--清空表数据
TRUNCATE student;
--清空表数据,自增从1开始
TRUNCATE student RESTART IDENTITY;
4、函数中获取操作行数,类似SQLServer中几行受影响
r_count integer :=0;
GET DIAGNOSTICS r_count := row_count;
5、函数中返回结果集(返回数据列要对应)
--返回类型改为实体表
RETURNS SETOF md_users
--返回查询结果
RETURN QUERY SELECT * FROM md_Users u WHERE u.userid = _userid;
返回类型也可以是自定义表(返回数据列要对应)
RETURNS TABLE(moneytotal numeric, counttotal bigint, persontotal bigint)
6、SQL拼接
SqlStr text;--声明变量
_Condition text;--声明变量
SqlStr:='SELECT aa ';
SqlStr:=SqlStr||',0.00 as CardTotal,0.00 as AppTotal FROM public.md_CashDeposit WHERE ' || _Condition || ';';
return QUERY execute SqlStr;--返回类型为结果集时
7、关联更新数据
update public.md_BathMachine as bm set UBotId=rb.UBotId from public.md_SchoolRoomFloorBind as rb
where bm.RoomFloorId=rb.RoomFloorId and rb.ProjectType=_ProjectType;
8、时间相关处理
SELECT NOW(); --2020-08-11 20:03:50
SELECT CURRENT_TIMESTAMP;--2020-08-11 20:03:59
SELECT CURRENT_TIME ;--20:04:10
SELECT CURRENT_DATE;--2020-08-11
SELECT NOW() + INTERVAL '10 year';--2030-08-11 20:05:52 min/year/month/day/hour/sec/
9、查询是如果为NULL时重新赋值,类似MSSQL中ISNULL
SELECT COALESCE(NULL,'123') != '13';
10、判断否个字段中是否包含否字符串,类似CHARINDEX(@Param,ColumnName)
SELECT distinct FloorNo,HouseId FROM public.v_SchoolRoomFloor WHERE POSITION('13000205F100001' IN UInstallId) >0 AND HouseId=1 AND Status=1;
SELECT distinct FloorNo,HouseId FROM public.v_SchoolRoomFloor WHERE STRPOS(UInstallId,'13000205F100001') >0 AND HouseId=1 AND Status=1;
--可查询多个
SELECT distinct FloorNo,HouseId FROM public.v_SchoolRoomFloor WHERE (STRING_TO_ARRAY('13000205F100001,1211212', ',') && STRING_TO_ARRAY(UInstallId, ','))
11、字段操作
ALTER TABLE public.md_bathnbonoffvalve ALTER COLUMN status SET DEFAULT '1'::integer;--修改字段
ALTER TABLE md_WattMachine ADD COLUMN IsAllowClose bool NOT NULL DEFAULT true;--添加字段
12、生成分页SQL语句
public static string GetNpgSqlPagingSql(PageCriteria criteria)
{
var sbSql = new StringBuilder();
//效率比较慢
sbSql.AppendFormat("select * from ( select row_number() over(order by {0}) as rowid,* from {1}) as subt \n", criteria.Sort, criteria.TableName);
sbSql.AppendFormat("where subt.rowid>=({0}-1)*{1}+1 and subt.rowid<={0}*{1};\n", criteria.CurrentPage, criteria.PageSize);
//PGSQL 自带OFFSET 功能,发现效率更高点
var tableWhereStr = criteria.TableName;
if (!string.IsNullOrEmpty(criteria.Condition))
{
tableWhereStr += " where " + criteria.Condition;
}
sbSql.AppendFormat("select (select count(1) from {0}) RecordCount,* from {0} order by {1} LIMIT {2} OFFSET {3}",
tableWhereStr,
criteria.Sort,
criteria.PageSize,
(criteria.CurrentPage - 1) * criteria.PageSize);
return sbSql.ToString();
}
/// <summary>
/// 封装查询条件相关信息的类
/// </summary>
[Serializable]
public class PageCriteria
{
public string TableName { get; set; }
public string PrimaryKey { get; set; }
public int PageSize { get; set; }
public int CurrentPage { get; set; }
public string Sort { get; set; }
public string Condition { get; set; }
/// <summary>
/// 总行数
/// </summary>
public int RecordCount { get; set; }
}
13、获取时间部分
SELECT DATE_PART('hour',NOW());
SELECT DATE_PART('minute',NOW());
SELECT DATE_PART('second',NOW());
14、类型转换
SELECT cast('1234.33' as NUMERIC(18,2));
SELECT to_number('12121231231.8', '99999999999.99');
SELECT to_char(1234566.35, '99999999999');
SELECT to_number('1212.8', '99G999D9S');
SELECT to_number('12121231231.8', '99999999999.99');
SELECT replace('123456789', '456', '000');
15、数据库备份还原
BEGIN
找到数据库安装的bin目录,然后在此处打开cmd
备份数据库,指令如下:
pg_dump -h 164.82.233.54 -U postgres databasename > C:\databasename.bak
指令解释:如上命令,pg_dump 是备份数据库指令,164.82.233.54是数据库的ip地址(必须保证数据库允许外部访问的权限哦~)
当然本地的数据库ip写 localhost;postgres 是数据库的用户名;databasename 是数据库名。> 意思是导出到C:\databasename.bak文件里,
如果没有写路径,单单写databasename.bak文件名,那么备份文件会保存在C: \Program Files\PostgreSQL\9.0\bin 文件夹里。
恢复数据库,指令如下:
psql -h localhost -U postgres -d databasename < C:\databasename.bak
指令解释:如上命令,psql是恢复数据库命令,localhost是要恢复到哪个数据库的地址,当然你可以写上ip地址,也就是说能远程恢复(必须保证 数据库允许外部访问的权限哦~);
postgres 就是要恢复到哪个数据库的用户;databasename 是要恢复到哪个数据库。< 的意思是把C:\databasename.bak文件导入到指定的数据库里。
在linux里依然有效。有一个值得注意的是:如果直接进入PostgreSQL的安装目录bin下,执行命令,可能会出现 找不到pg_dump,psql的现象,我们在可以这样:
备份:
/opt/PostgreSQL/9.5/bin/pg_dump -h 164.82.233.54 -U postgres databasename > databasename.bak
恢复:
/opt/PostgreSQL/9.5/bin/psql -h localhost -U postgres -d databasename < databasename.bak
16、通过mac(某个字段)关联Update表数据
UPDATE md_WattMachine wmm
SET WalletAmount=tt."data"*0.65
FROM (
SELECT wm.mac,wm.walletamount,wl."data" FROM md_WattMachine wm
JOIN md_WattUseLog wl ON wm.mac=wl.mac AND wl."time"='2020/9/1 13:00:00'
) AS tt
WHERE wmm.mac = tt.mac;
17、数据库使用中无法删除解决办法
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname='testdb' AND pid<>pg_backend_pid();
testdb 为数据库名称,执行上面语句后再执行删除即可
使用数据库管理工具执行 DROP DATABASE testdb 时可能还是不行,所以用官方的PgAdmin 直接鼠标操作就可以了
18、变量赋值
DECLARE _botId TEXT := '';
SELECT s.ubotid INTO _botId FROM md_school s WHERE s.id=_schoolid;
19、游标使用
CREATE OR REPLACE FUNCTION public.fn_wattuselogtableadd(readingxml text)
RETURNS numeric
LANGUAGE plpgsql
AS $function$
DECLARE
_readingxml XML := readingxml;--只是传进来没有用到,作为形参在程序中必须存在
WattUseLog_Cursor CURSOR FOR SELECT id,time FROM public.ReadingTemp;
r_result integer :=-2;-- -2电表未录入系统 1新增成功
r_count integer :=0;
_tempid integer=0;
_mac TEXT := '';
_time timestamp := now();
BEGIN
CREATE TEMPORARY TABLE OrderTemp(
OrderId VARCHAR(18),
SchoolId INT,
SchoolName VARCHAR(50),
AreaId INT,
AreaName VARCHAR(50),
HouseId INT,
HouseName VARCHAR(50),
FloorNo VARCHAR(20),
RoomNo VARCHAR(20),
UBotId CHAR(15),
UInstallId CHAR(15),
Mac VARCHAR(20),
Rate DECIMAL(18,2),
WattMultiple INT,
LastData DECIMAL(18,2),
cid VARCHAR(18),
data DECIMAL(18,2),
time timestamp,
updtime timestamp,
UsedData DECIMAL(18,2),
UsedAmount DECIMAL(18,2)
);
IF EXISTS(SELECT 1 FROM ReadingTemp t JOIN md_WattMachine vm ON vm.Mac=t.id AND vm.Status>-1) THEN
INSERT INTO OrderTemp
SELECT
t.OrderId
,vm.SchoolId
,vm.SchoolName
,vm.AreaId
,vm.AreaName
,vm.HouseId
,vm.HouseName
,vm.FloorNo
,vm.RoomNo
,vm.UBotId
,vm.UInstallId
,t.id
,vm.Rate --默认获取电表设置的费率
,vm.WattMultiple
,COALESCE(w.DATA,0) as data
,t.cid
,t.data
,t.time
,t.updtime
,0
,0
FROM ReadingTemp t JOIN md_WattMachine vm ON vm.Mac=t.id AND vm.Status>-1
LEFT JOIN (
select Mac,data from (select row_number() over(partition by Mac order by time desc ) as keyId,Mac,data from md_WattUseLog) t where t.keyId =1
) w ON vm.Mac=w.Mac;
UPDATE OrderTemp SET UsedData=(data - LastData),UsedAmount=((data - LastData) * Rate * WattMultiple);
-- 打开游标
OPEN WattUseLog_Cursor;
LOOP
-- -- 获取记录放入film
FETCH WattUseLog_Cursor INTO _mac,_time;
EXIT WHEN NOT FOUND;
IF NOT EXISTS (SELECT 1 FROM md_WattUseLog WHERE mac=_mac AND "time"=_time) THEN
INSERT INTO md_WattUseLog(
OrderId,SchoolId,SchoolName,AreaId,AreaName,HouseId,HouseName,FloorNo,RoomNo,UBotId,UInstallId,
ProjectType,Mac,MacName,Rate,WattMultiple,cid,data,time,updtime,UsedData,UsedAmount,createtime)
SELECT
b.OrderId, b.SchoolId, b.SchoolName, b.AreaId, b.AreaName, b.HouseId, b.HouseName, b.FloorNo, b.RoomNo,
b.UBotId, b.UInstallId, 'watt' ProjectType ,b.Mac, '海兴' MacName, b.Rate,b.WattMultiple, b.cid, to_number(to_char(b.data, '99999999999.99'), '99999999999.99'),
b.time, b.updtime, b.UsedData, b.UsedAmount, now()
FROM OrderTemp b WHERE b.Mac=_mac AND b.time=_time;
-- GET DIAGNOSTICS r_count := row_count; --获取操作行数
r_result := 1; --新增成功
ELSE
r_result := -3; --已有重复数据
END IF;
END LOOP;
-- IF r_count >0 THEN
-- r_result := 1; --新增成功
--同步电表钱包余额
UPDATE md_WattMachine wm SET WalletAmount=(WalletAmount-orders.UsedAmount),UpdateTime=NOW()
FROM
(SELECT o.UsedAmount,o.mac FROM md_WattMachine m JOIN OrderTemp o ON o.Mac=m.Mac and m.Status >-1) AS orders
WHERE wm.mac = orders.mac and wm.Status >-1;
--同步消费单余额
UPDATE md_WattUseLog wul SET WalletAmount=orders.WalletAmount
FROM
(SELECT wm.WalletAmount,wm.Mac,wm.Status,o.time FROM md_WattUseLog wl
JOIN md_WattMachine wm ON wl.Mac=wm.Mac and wm.Status >-1
JOIN OrderTemp o on o.time=wl.time) AS orders
WHERE wul.mac = orders.mac and wul.time=orders.time;
-- ELSE
-- r_result := 0;
-- END IF;
END IF;
CLOSE WattUseLog_Cursor;-- 关闭游标
-- DEALLOCATE WattUseLog_Cursor; --PgSql没有此写法
RETURN r_result;
END;
$function$
;
PostgresSQL 常用操作方法的更多相关文章
- js数组常用操作方法小结(增加,删除,合并,分割等)
本文实例总结了js数组常用操作方法.分享给大家供大家参考,具体如下: var arr = [1, 2, 3, 4, 5]; //删除并返回数组中第一个元素 var theFirst = arr.shi ...
- Set对象常用操作方法和遍历
Set<String> set = new HashSet<String>(); /** * set的常用操作方法有: * add()向集合添加元素 clear()清空集合元素 ...
- Python文件常用操作方法
Python文件常用操作方法 一.对File对象常用操作方法: file= open(file, mode='r', buffering=-1, encoding=None, errors=None, ...
- python 字符串常用操作方法
python 字符串常用操作方法 python 字符串操作常用操作,如字符串的替换.删除.截取.赋值.连接.比较.查找.分割等 1.去除空格 str.strip():删除字符串两边的指定字符,括号的写 ...
- C++中vector容器的常用操作方法实例总结
C++中vector容器的常用操作方法实例总结 参考 1. C++中vector容器的常用操作方法实例总结: 完
- 进阶Java编程(2)线程常用操作方法
线程常用操作方法 多线程的主要操作方法都在Thread类中定义的. 1,线程的命名和取得 多线程的运行状态是不确定的,那么在程序的开发之中为了可以获取到一些需要使用到的线程就只能依靠线程的名字来进行操 ...
- python字符串的索引切片和常用操作方法,for循环
---恢复内容开始--- 一.字符串的索引与切片 1.索引 s = 'ASDFGHJKL' 有序序列,索引--index:从0开始 s1 = s[0],取出单个元素:A: s1是个全新的字符串和原字符 ...
- day2_python之数据类型常用操作方法
一.什么可变数据类型和不可变数据类型 可变数据类型:value值改变,id值不变:不可变数据类型:value值改变,id值也随之改变. 如何确定一种数据类型是可变的还是不可变的: 根据可变数据类型与不 ...
- dom节点及对节点的常用操作方法
dom节点及对节点的常用操作方法 在说dom节点前,先来看看页面的呈现: dom渲染流程: 1.浏览器解析html源码,然后创建一个DOM树. 在DOM树中,每一个HTML标签都有一个对应的节点(元 ...
- 003_python的str切片,str常用操作方法,for循环,集合,深浅copy
基础数据类型 基础数据类型,有7种类型,存在即合理. 1.int 整数 主要是做运算的 .比如加减乘除,幂,取余 + - * / ** %... 2.bool布尔值 判断真假以及作为条件变量 3.s ...
随机推荐
- javaSE--核心之一:IO流
Java IO流框架结构: IO的主要内容包括输入.输出两种IO流,这两种流中又分为字节流和字符流,字节流是以字节为单位来处理输入.输出流,而字符流是以字符为单位来处理输入.输出流. InputStr ...
- 在Windows模拟器中使用LVGL8.3
引言 LVGL是一个跨平台.轻量级.易于移植的图形库.也因其支持大量特性和其易于裁剪,配置开关众多,且版本升级较快,不同版本之间存在一定的差异性,相关的使用教程有一定的滞后性,由于缺少最新版本的中文教 ...
- 数电第五周周结_by_yc
数电第五周周结_by_yc 基本要点: 组合逻辑电路的行为特点.经典组合逻辑电路的设计.PPA优化 组合逻辑电路设计要点: ①敏感变量列表应包含所有会影响输出的控制量: ②条件语句的完全描述, ...
- 持续发烧,聊聊Dart语言的并发处理,能挑战Go不?
前言 貌似关于Dart的文章没流量啊,就算在小编关怀上了首页,看得人还是很少的. 算了,今天持续发烧,再来写写如何使用 Dart 语言的并发操作.说起并发操作,玩 Go 的同学该笑了,这就是我们的看家 ...
- Linux 下的输入输出和重定向示例
Linux 下的输入输出和重定向示例 作者:Grey 原文地址: 博客园:Linux 下的输入输出和重定向示例 CSDN:Linux 下的输入输出和重定向示例 说明 Linux 下的输入输出有如下三种 ...
- python虚拟环境和venv的使用
目录 1.环境与虚拟环境 2.查看帮助 3.--system-site-package 命令 4.创建虚拟环境 5.激活/关闭虚拟环境 6.保存和复制虚拟环境 7.改变虚拟环境所指向的真实python ...
- 使用Google OR-Tools分析过去20年中国金融资产最佳配置组合
前两天,在朋友圈里看到一张截至2022年Q2的金融资产历年收益图如下,图中列举了国内从2005年到2022年近20年主要的金融资产历年收益率,随产生想法分析和验证下面几个问题: 过去20年,基于怎样的 ...
- 常用内置模块os sys json
今日内容回顾 目录 今日内容回顾 os模块 sys模块 json模块 json模块实战 os模块 sys模块 json模块 os模块 os模块主要与代码运行的操作系统打交道 1.创建目录(文件夹) i ...
- Vue3 企业级优雅实战 - 组件库框架 - 9 实现组件库 cli - 上
上文搭建了组件库 cli 的基础架子,实现了创建组件时的用户交互,但遗留了 cli/src/command/create-component.ts 中的 createNewComponent 函数,该 ...
- Python实验报告(第6章)
实验6:函数 一.实验目的和要求 1.掌握函数的创建和调用: 2.了解不同的参数如何进行传递: 3.了解返回值的应用: 4.学习变量的作用域: 5.学习匿名函数(lambda). 二.实验环境 软件版 ...