」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 在 PostgreSQL 中建立自訂函數

在 PostgreSQL 中建立自訂函數

發佈於2024-07-30
瀏覽:376

Creating Custom Functions In PostgreSQL

在PostgreSQL中,可以创建自定义函数来解决复杂的问题。

这些可以使用默认的 PL/pgSQL 脚本语言编写,也可以使用其他脚本语言编写。

Python、Perl、Tcl 和 R 是支持的一些脚本语言。

虽然 PL/pgSQL 随任何 Postgres 安装一起提供,但要使用其他语言需要进行一些设置。

安装扩展

在使用扩展之前,需要安装扩展包。

在 Ubuntu 上你可以运行:

Perl

sudo apt-get -y install postgresql-plperl-14

软件包名称“postgresql-plperl-14”特定于 PostgreSQL 版本 14。如果您使用的是不同版本的 PostgreSQL,则需要更改软件包名称中的版本号以匹配您安装的 PostgreSQL 版本。

Python 3

sudo apt-get install postgresql-plpython3-14

激活扩展

要在 PostgreSQL 中激活扩展,必须使用 CREATE EXTENSION 语句定义扩展。

Perl

CREATE EXTENSION plperl;

Python

CREATE EXTENSION plpython3;

你好世界示例

创建扩展后,可以使用该扩展创建自定义函数。

Perl

CREATE OR REPLACE FUNCTION hello(name text) 
RETURNS text AS $$
    my ($name) = @_;
    return "Hello, $name!";
$$ LANGUAGE plperl;

Python

CREATE OR REPLACE FUNCTION hello(name text)
RETURNS text AS $$
    return "Hello, "   name   "!"
$$ LANGUAGE plpython3;

逐行分解

CREATE OR REPLACE FUNCTION hello(name text)

这一行是在 Postgres 中创建函数的方式。通过使用 CREATE 或 REPLACE,它将用新函数覆盖已使用名称 hello 定义的任何函数。

使用 CREATE FUNCTION hello(name text) 将阻止该函数覆盖现有函数,并且如果该函数已存在,则会出错。


RETURNS text AS $$

这定义了将返回什么 Postgres 数据类型,重要的是指定的数据类型是 Postgres 识别的类型。如果已经定义了自定义数据类型,则可以指定自定义数据类型。

$$ 是一个分隔符,用于标记代码块的开始和结束。在这一行中,它标记了代码块的开始。

开始和结束$$之间的所有代码都将由Postgres执行


$$ LANGUAGE plperl;

$$ 表示脚本的结尾,并告诉 Postgres 脚本应该解析为哪种语言。

使用功能

函数可以像任何内置 Postgres 函数一样使用

SELECT hello('world');

这将返回一个值为 Hello world!

的列

函数可以是更复杂查询的一部分:

SELECT id, title, hello('world') greeting FROM table;

更复杂的例子

这是一个示例函数,它接受来自字段的文本并返回字数。

CREATE OR REPLACE FUNCTION word_count(paragraph text)
RETURNS json AS $$
use strict;
use warnings;

my ($text) = @_;

my @words = $text =~ /\w /g;
my $word_count = scalar @words;

my $result = '{' .
    '"word_count":' . $word_count .
'}';
return $result;
$$ LANGUAGE plperl;

这将返回带有字数统计的 JSON 格式结果。


我们可以在函数中添加更详细的统计数据。

CREATE OR REPLACE FUNCTION word_count(paragraph text)
RETURNS json AS $$
use strict;
use warnings;

my ($text) = @_;

my @words = $text =~ /\w /g;

my $word_count = scalar @words;

my $sentence_count = ( $text =~ tr/!?./!?./ ) || 0;

my $average_words_per_sentence =
  $sentence_count > 0 ? $word_count / $sentence_count : 0;

my $result = '{' .
    '"word_count":' . $word_count . ',' .
    '"sentence_count":' . $sentence_count . ',' .
    '"average_words_per_sentence":"' . sprintf("%.2f", $average_words_per_sentence) . '"' .
'}';

return $result;
$$ LANGUAGE plperl SECURITY DEFINER;

现在当我们在查询中使用它时

SELECT word_count(text_field) word_count FROM table

它将返回 JSON,如

{"word_count":116,"sentence_count":15,"average_words_per_sentence":"7.73"}

安全考虑

使用自定义函数或外部脚本语言时,需要考虑其他安全注意事项。在可用性和安全性之间取得适当的平衡可能是一种兼顾的行为。

安全定义者与安全调用者

在上一个函数中,SECURITY DEFINER 选项被添加到创建函数语句中。

从安全角度考虑您希望函数如何运行非常重要。

默认行为是使用 SECURITY INVOKER。这将以运行该函数的用户的权限运行该函数。

SECURITY DEFINER 提供了对授予功能的权限的更多控制。使用此模式,该函数将以创建该函数的用户的权限运行。

这可能是好事,也可能是坏事,如果一个函数是由具有有限权限的用户创建的,那么对数据库造成的损害就很小。

如果该函数是由具有高访问权限的用户创建的,则该函数将以相同的权限运行。根据函数的类型,这可能允许用户以比授予的更多开放权限运行该函数。

有时这很有用,例如,如果用户没有表的读取权限,但在函数内需要读取,则使用 SECURITY DEFINER 可以允许函数运行所需的读取权限。


受信任和不受信任的扩展

创建上面的扩展时,使用了plperl和plpython3。在大多数情况下,这些是正确使用的扩展。

这些扩展对服务器文件系统和系统调用的访问受到限制。

扩展也可以使用 u (plpython3u, plperlu)

创建

这些是不受信任的扩展,允许对服务器文件系统进行更多访问。

在某些情况下可能需要这样做,例如,如果您想使用 Perl 模块、Python 库或使用系统调用。

在上面的示例中,JSON 输出生成为字符串,如果需要,可以使用 perl JSON 模块将数据编码为 JSON。为此,需要使用不受信任的扩展来访问 JSON 模块。

建议不要使用不受信任的扩展,但如有必要,请谨慎使用并了解潜在风险。

如果正在使用 Perl,当使用不受信任的扩展时,Perl 将以污点模式运行。

最后的想法

能够利用 Perls 高级文本处理和内存管理,或者 PostgreSQL 中的 Python 数据分析库可能是一个非常强大的工具。

将复杂的任务交给更适合处理该任务的工具可以减少数据库的开销。

一如既往,在使用自定义函数和外部脚本语言时,请采取预防措施以确保安全使用。

版本聲明 本文轉載於:https://dev.to/mrpercival/creating-custom-functions-in-postgresql-52bn?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • Next.js - 概述
    Next.js - 概述
    本文作為初學者友好的指南和使用 Next.js 的步驟。 Next.js 是一個用於建立 Web 應用程式的靈活框架。相反,它是一個建立在 Node.js 之上的 React 框架。 設定您的 Next.js 專案 要啟動新的 Next.js 項目,您需要在電腦上安裝 Node.js。 安裝 ...
    程式設計 發佈於2024-11-02
  • 如何在程式碼中使用 Unsplash 圖片
    如何在程式碼中使用 Unsplash 圖片
    身為從事新 SaaS 專案的開發人員,我需要直接透過 URL 連結一些 Unsplash 圖片。 最初,我看到一篇推薦使用 https://source.unsplash.com/ API 的文章(連結)。但是,此方法不再有效,僅從 URL 欄位複製連結並不能提供嵌入所需的直接圖像 URL。 h...
    程式設計 發佈於2024-11-02
  • 如何合併關聯數組、處理缺失鍵、填滿預設值?
    如何合併關聯數組、處理缺失鍵、填滿預設值?
    合併多個關聯數組並添加具有預設值的缺失列將關聯數組與不同的鍵集組合起來創建統一的數組可能具有挑戰性。這個問題探索了一種實現此目的的方法,所需的輸出是一個數組,其中鍵被合併,缺失的列用預設值填充。 為了實現這一點,建議結合使用 array_merge 函數精心設計的鍵數組:$keys = array(...
    程式設計 發佈於2024-11-02
  • 透過 testcontainers-go 和 docker-compose 來利用您的測試套件
    透過 testcontainers-go 和 docker-compose 來利用您的測試套件
    Welcome back, folks! Today, we will cover the end-to-end tests in an intriguing blog post. If you've never written these kinds of tests or if you stri...
    程式設計 發佈於2024-11-02
  • 以下是一些適合您文章的基於問題的標題:

**直接簡潔:**

* **如何在Windows控制台中正確顯示UTF-8字元? ** **
* **為什麼傳統方法無法顯示
    以下是一些適合您文章的基於問題的標題: **直接簡潔:** * **如何在Windows控制台中正確顯示UTF-8字元? ** ** * **為什麼傳統方法無法顯示
    在Windows 控制台中正確顯示UTF-8 字元使用傳統方法在Windows 控制台中顯示UTF-8 字元的許多嘗試均失敗正確渲染擴充字元。 失敗嘗試:一個使用 MultiByteToWideChar() 和 wprintf() 的常見方法被證明是無效的,只留下 ASCII 字元可見。此外,使用 ...
    程式設計 發佈於2024-11-02
  • ReactJS 的模擬介紹
    ReactJS 的模擬介紹
    ReactJS 19:重要部份 並發模式增強: ReactJS 19 中最大的改進是並發模式,它不僅在應用程式自身更新時保持UI 平滑和響應靈敏,而且還確保了無縫界面,尤其是在復雜的過渡(例如動畫)時。 改進的伺服器元件: 在 Python 的引領下,ReactJ...
    程式設計 發佈於2024-11-02
  • 首屆DEV網頁遊戲挑戰賽評審
    首屆DEV網頁遊戲挑戰賽評審
    我被要求對DEV團隊9月份組織的第一屆網頁遊戲挑戰賽提交的參賽作品進行評判,結果在10月初發布。 我們幾個月來一直在 DEV 上組織挑戰(迷你黑客馬拉松),併計劃宣布我們的第一個網頁遊戲挑戰。鑑於您在遊戲社群 和 dev.to 的專業知識和參與度,我們想知道您是否有興趣成為客座評審。 誰能對此說...
    程式設計 發佈於2024-11-02
  • 購買經過驗證的現金應用程式帳戶:安全可靠的交易
    購買經過驗證的現金應用程式帳戶:安全可靠的交易
    Buying verified Cash App accounts is not recommended. It can lead to security risks and potential account bans. If you want to more information just k...
    程式設計 發佈於2024-11-02
  • 為什麼 `std::function` 缺乏相等比較?
    為什麼 `std::function` 缺乏相等比較?
    揭開std::function 的等式可比性之謎難題:為什麼是std::&&]難題:為什麼是std:: function,現代C 程式碼庫的一個組成部分,不具備相等比較功能?這個問題從一開始就困擾著程式設計師,導致管理可呼叫物件集合的混亂和困難。 早期的歧義:在C 語言的早期草案中11 標準中,op...
    程式設計 發佈於2024-11-02
  • JavaScript 類型檢查 |程式設計教學
    JavaScript 類型檢查 |程式設計教學
    介紹 本文涵蓋以下技術技能: 在本實驗中,我們將探索一個 JavaScript 函數,該函數檢查提供的值是否屬於指定類型。我們將使用 is() 函數,它利用建構子屬性和 Array.prototype.includes() 方法來確定值是否屬於指定類型。本實驗將幫助您更了解 Jav...
    程式設計 發佈於2024-11-02
  • 使用 Streamlit 將機器學習模型部署為 Web 應用程式
    使用 Streamlit 將機器學習模型部署為 Web 應用程式
    介绍 机器学习模型本质上是一组用于进行预测或查找数据模式的规则或机制。简单地说(不用担心过于简单化),在 Excel 中使用最小二乘法计算的趋势线也是一个模型。然而,实际应用中使用的模型并不那么简单——它们通常涉及更复杂的方程和算法,而不仅仅是简单的方程。 在这篇文章中,我将首先构...
    程式設計 發佈於2024-11-02
  • ## utf8_unicode_ci 與 utf8_bin:哪一種 MySQL 排序規則最適合德國網站?
    ## utf8_unicode_ci 與 utf8_bin:哪一種 MySQL 排序規則最適合德國網站?
    為德語選擇最佳MySQL 排序規則為德語選擇最佳MySQL 排序規則在設計為德語受眾量身定制的網站時,支持像ä、 ü 和ß。當涉及特定於語言的要求時,排序規則的選擇起著重要作用。 字元集和排序規則對於字元處理,UTF-8 仍然是首選選項,提供廣泛的字元支援。至於排序規則,則需要考慮德語特定字元。 排...
    程式設計 發佈於2024-11-02
  • 異常處理基礎知識
    異常處理基礎知識
    Java中的例外處理由五個關鍵字管理:try、catch、 throw、throws和finally。 這些關鍵字構成了一個相互關聯的子系統。 要監視的指令位於 try 區塊內。 如果try區塊中發生異常,則會拋出異常。 程式碼可以使用catch捕獲並處理異常。 系統異常由Java執行時...
    程式設計 發佈於2024-11-02
  • 好的第一期:做出您的第一個開源貢獻
    好的第一期:做出您的第一個開源貢獻
    嘿,未來的開源貢獻者! ? 一開始為開源做出貢獻可能會令人生畏,尤其是當專案有數千行程式碼並且對問題進行深入討論時。但這就是為什麼好的首要問題存在。它們就像是一個友好的邀請,讓你嘗試並熟悉操作,而不會迷失在雜草中。將它們視為幫助您開始騎乘的輔助輪。 無論如何,什麼是好的第一期? ...
    程式設計 發佈於2024-11-02
  • 目錄:Django 基礎知識
    目錄:Django 基礎知識
    點此收聽我的直播 目錄:Django 基礎 Django簡介 Django框架概述 安裝Python 設定虛擬環境 安裝 Django 創建您的第一個 Django 專案 Django 專案架構 瞭解 Django 的專案佈局 管理 Django 設定 配置資料庫設定 urls.py、views....
    程式設計 發佈於2024-11-02

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3