1. 程式人生 > 實用技巧 >PostgresSQL 知識點記錄

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;

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);
        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、資料庫備份還原

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