CREATE FUNCTION (SQL وPython)
ينطبق على: Databricks SQL Databricks Runtime
إنشاء دالة عددية أو جدول SQL تأخذ مجموعة من الوسيطات وترجع قيمة عددية أو مجموعة من الصفوف.
ينطبق على: Databricks SQL Databricks Runtime 13.3 LTS وما فوق
إنشاء دالة عددية Python تأخذ مجموعة من الوسيطات وترجع قيمة عددية.
تتطلب Python UDFs كتالوج Unity على مستودعات SQL بلا خادم أو pro، أو مجموعة كتالوج Unity لمستخدم مشترك أو واحد.
ينطبق على: Databricks SQL Databricks Runtime 14.1 وما فوق
بالإضافة إلى استدعاء المعلمة الموضعية، يمكنك أيضا استدعاء SQL وPython UDF باستخدام استدعاء المعلمة المسماة.
بناء الجملة
CREATE [OR REPLACE] [TEMPORARY] FUNCTION [IF NOT EXISTS]
function_name ( [ function_parameter [, ...] ] )
{ [ RETURNS data_type ] |
RETURNS TABLE [ ( column_spec [, ...]) ] }
[ characteristic [...] ]
{ AS dollar_quoted_string | RETURN { expression | query } }
function_parameter
parameter_name data_type [DEFAULT default_expression] [COMMENT parameter_comment]
column_spec
column_name data_type [COMMENT column_comment]
characteristic
{ LANGUAGE { SQL | PYTHON } |
[NOT] DETERMINISTIC |
COMMENT function_comment |
[CONTAINS SQL | READS SQL DATA] }
المعلمات
أو استبدال
إذا تم تحديدها، يتم استبدال الدالة بنفس الاسم والتوقيع (عدد المعلمات وأنواع المعلمات). لا يمكنك استبدال دالة موجودة بتوقيع مختلف. هذا مفيد بشكل رئيسي لتحديث نص الدالة ونوع الإرجاع للدالة. لا يمكنك تحديد هذه المعلمة باستخدام
IF NOT EXISTS
.مؤقت
نطاق الدالة التي يتم إنشاؤها. عند تحديد
TEMPORARY
، تكون الدالة التي تم إنشاؤها صالحة ومرئية في جلسة العمل الحالية. لم يتم إدخال مستمر في الكتالوج.إذا لم يكن موجودا
إذا تم تحديدها، يتم إنشاء الدالة فقط عندما لا تكون موجودة. ينجح إنشاء الدالة (لا يتم طرح أي خطأ) إذا كانت الدالة المحددة موجودة بالفعل في النظام. لا يمكنك تحديد هذه المعلمة باستخدام
OR REPLACE
.-
اسم للدالة. بالنسبة إلى دالة دائمة، يمكنك اختياريا تأهيل اسم الدالة باسم مخطط. إذا لم يكن الاسم مؤهلا، يتم إنشاء الدالة الدائمة في المخطط الحالي.
function_parameter
تحديد معلمة للدالة.
-
يجب أن يكون اسم المعلمة فريدا داخل الدالة .
-
أي نوع بيانات معتمد. بالنسبة إلى Python،
data_type
يتم تحويلها إلى نوع بيانات Python وفقا لتعيين اللغة هذا. -
ينطبق على: Databricks SQL Databricks Runtime 10.4 LTS وما فوق
افتراضي اختياري لاستخدامه عندما لا يقوم استدعاء دالة بتعيين وسيطة للمعلمة .
default_expression
يجب أن يكون قابلا للصب إلىdata_type
. يجب ألا يشير التعبير إلى معلمة أخرى أو يحتوي على استعلام فرعي.عند تحديد افتراضي لمعلمة واحدة، يجب أن تحتوي جميع المعلمات التالية أيضا على افتراضي.
DEFAULT
معتمد فقطLANGUAGE SQL
. تعليق التعليق
وصف اختياري للمعلمة.
comment
يجب أن تكون قيمة حرفيةSTRING
.
-
إرجاع data_type
نوع بيانات الإرجاع للدالة العددية. بالنسبة إلى Python UDFs، يجب أن تتطابق القيم المرجعة تماما مع نوع البيانات كما هو محدد في
data_type
. وإلا، لمنع تحويلات النوع غير المتوقعة، ستفشل الدالة.بالنسبة إلى SQL UDF، هذه العبارة اختيارية. سيتم اشتقاق نوع البيانات من نص الدالة إذا لم يتم توفيره.
إرجاع الجدول [ (column_spec [,...] ) ]
تحدد هذه العبارة الدالة كدالة جدول. اختياريا فإنه يحدد أيضا توقيع نتيجة دالة الجدول. إذا لم يتم تحديد أي column_spec، اشتقاقه من نص SQL UDF.
RETURNS TABLE
معتمد فقطLANGUAGE SQL
.-
يجب أن يكون اسم العمود فريدا داخل التوقيع.
-
أي نوع بيانات معتمد.
column_comment التعليق
وصف اختياري للعمود.
comment
يجب أن تكون قيمة حرفيةSTRING
.
-
RETURN { expression | query }
نص الدالة. بالنسبة للدالة العددية، يمكن أن تكون إما استعلاما أو تعبيرا. بالنسبة لدالة جدول، يمكن أن تكون استعلاما فقط. لا يمكن أن يحتوي التعبير على:
- دالات التجميع
- دوال النافذة
- دالات الترتيب
- وظائف إنتاج الصف مثل تنفجر
ضمن نص الدالة، يمكنك الرجوع إلى المعلمة باسمها غير المؤهل أو عن طريق تأهيل المعلمة باسم الدالة.
AS dollar_quoted_definition
dollar_quoted_definition
هي دالةbody
Python محاطة باثنين من المطابقة$[tag]$body$[tag]$
.tag
يمكن أن تكون سلسلة فارغة.أمثلة:
$$ return “Hello world” $$ $py$ return "Hello World" $py$
نوعي
جميع العبارات المميزة اختيارية. يمكنك تحديد أي عدد منها بأي ترتيب، ولكن يمكنك تحديد كل عبارة مرة واحدة فقط.
LANGUAGE SQL أو LANGUAGE PYTHON
لغة تنفيذ الدالة.
[NOT] القطعيه
ما إذا كانت الدالة حتمية أم لا. الدالة محددة عندما تقوم بإرجاع نتيجة واحدة فقط لمجموعة معينة من الوسيطات. يمكنك وضع علامة على دالة على أنها
DETERMINISTIC
عندما لا يكون نصها والعكس صحيح. قد يكون سبب ذلك هو تشجيع أو تثبيط تحسينات الاستعلام مثل الطي المستمر أو التخزين المؤقت للاستعلام. إذا لم تحدد خيار ths، يتم اشتقاقه من نص الدالة.function_comment التعليق
تعليق للدالة.
function_comment
يجب أن تكون سلسلة حرفية.يحتوي على بيانات SQL أو READS SQL
ما إذا كانت الدالة تقرأ البيانات بشكل مباشر أو غير مباشر من جدول أو طريقة عرض. عندما تقرأ الدالة بيانات SQL، لا يمكنك تحديد
CONTAINS SQL
. إذا لم تحدد أي من العبارتين، يتم اشتقاق الخاصية من نص الدالة.
المكتبات المدعومة في Python UDFs
لاستخدام أي تبعيات، استخدم import <package>
داخل نص الدالة. على سبيل المثال، راجع ما يلي:
CREATE FUNCTION […]
AS $$
import json
[... (rest of function definition)]
$$
تقتصر التبعيات على مكتبة Python القياسية والمكتبات التالية:
الحزمة | إصدار |
---|---|
بيض | 4.0.0 |
تجزئة | 4.0.0 |
charset-normalizer | 2.0.4 |
defusedxml | 0.7.1 |
googleapis-common-protos | 1.56.4 |
grpcio | 1.47.0 |
حالة grpcio | 1.47.0 |
مسار jmespath | 0.10.0 |
joblib | 1.1.0 |
numpy | 1.20.3 |
التغليف | 21.3 |
pandas | 1.3.4 |
بتسي | 0.5.2 |
protobuf | 4.21.5 |
pyarrow | 7.0.0 |
pyparsing | 3.0.9 |
python-dateutil | 2.8.2 |
pytz | 2021.3 |
scikit-learn | 0.24.2” |
شفرة | 1.7.1” |
أدوات الإعداد | 65.2.0 |
ستة | 1.16.0 |
threadpoolctl | 3.1.0 |
ترميزات الويب | 0.5.1 |
وكلاء المستخدم | 2.2.0 |
التشفير | 38.0.4 |
الأمثلة
- إنشاء دالة عددية SQL واستخدامها
- إنشاء واستخدام دالة تستخدم DEFAULTs
- إنشاء دالة جدول SQL
- استبدال دالة SQL
- وصف دالة SQL
- إنشاء وظائف Python
إنشاء دالة عددية SQL واستخدامها
> CREATE VIEW t(c1, c2) AS VALUES (0, 1), (1, 2);
-- Create a temporary function with no parameter.
> CREATE TEMPORARY FUNCTION hello() RETURNS STRING RETURN 'Hello World!';
> SELECT hello();
Hello World!
-- Create a permanent function with parameters.
> CREATE FUNCTION area(x DOUBLE, y DOUBLE) RETURNS DOUBLE RETURN x * y;
-- Use a SQL function in the SELECT clause of a query.
> SELECT area(c1, c2) AS area FROM t;
0.0
2.0
-- Use a SQL function in the WHERE clause of a query.
> SELECT * FROM t WHERE area(c1, c2) > 0;
1 2
-- Compose SQL functions.
> CREATE FUNCTION square(x DOUBLE) RETURNS DOUBLE RETURN area(x, x);
> SELECT c1, square(c1) AS square FROM t;
0 0.0
1 1.0
-- Create a non-deterministic function
> CREATE FUNCTION roll_dice()
RETURNS INT
NOT DETERMINISTIC
CONTAINS SQL
COMMENT 'Roll a single 6 sided die'
RETURN (rand() * 6)::INT + 1;
-- Roll a single 6-sided die
> SELECT roll_dice();
3
إنشاء واستخدام دالة تستخدم DEFAULTs
-- Extend the function to support variable number of sides and dice.
-- Use defaults to support a variable number of arguments
> DROP FUNCTION roll_dice;
> CREATE FUNCTION roll_dice(num_dice INT DEFAULT 1 COMMENT 'number of dice to roll (Default: 1)',
num_sides INT DEFAULT 6 COMMENT 'number of sides per die (Default: 6)')
RETURNS INT
NOT DETERMINISTIC
CONTAINS SQL
COMMENT 'Roll a number of n-sided dice'
RETURN aggregate(sequence(1, roll_dice.num_dice, 1),
0,
(acc, x) -> (rand() * roll_dice.num_sides)::int,
acc -> acc + roll_dice.num_dice);
-- Roll a single 6-sided die still works
> SELECT roll_dice();
3
-- Roll 3 6-sided dice
> SELECT roll_dice(3);
15
-- Roll 3 10-sided dice
> SELECT roll_dice(3, 10)
21
-- Roll 3 10-sided dice using named parameter invocation
> SELECT roll_dice(10 => num_sides, num_dice => 3)
17
-- Create a SQL function with a scalar subquery.
> CREATE VIEW scores(player, score) AS VALUES (0, 1), (0, 2), (1, 2), (1, 5);
> CREATE FUNCTION avg_score(p INT) RETURNS FLOAT
COMMENT 'get an average score of the player'
RETURN SELECT AVG(score) FROM scores WHERE player = p;
> SELECT c1, avg_score(c1) FROM t;
0 1.5
1 3.5
إنشاء دالة جدول SQL
-- Produce all weekdays between two dates
> CREATE FUNCTION weekdays(start DATE, end DATE)
RETURNS TABLE(day_of_week STRING, day DATE)
RETURN SELECT extract(DAYOFWEEK_ISO FROM day), day
FROM (SELECT sequence(weekdays.start, weekdays.end)) AS T(days)
LATERAL VIEW explode(days) AS day
WHERE extract(DAYOFWEEK_ISO FROM day) BETWEEN 1 AND 5;
-- Return all weekdays
> SELECT weekdays.day_of_week, day
FROM weekdays(DATE'2022-01-01', DATE'2022-01-14');
1 2022-01-03
2 2022-01-04
3 2022-01-05
4 2022-01-06
5 2022-01-07
1 2022-01-10
2 2022-01-11
3 2022-01-12
4 2022-01-13
5 2022-01-14
-- Return weekdays for date ranges originating from a LATERAL correlation
> SELECT weekdays.*
FROM VALUES (DATE'2020-01-01'),
(DATE'2021-01-01'),
(DATE'2022-01-01') AS starts(start),
LATERAL weekdays(start, start + INTERVAL '7' DAYS);
3 2020-01-01
4 2020-01-02
5 2020-01-03
1 2020-01-06
2 2020-01-07
3 2020-01-08
5 2021-01-01
1 2021-01-04
2 2021-01-05
3 2021-01-06
4 2021-01-07
5 2021-01-08
1 2022-01-03
2 2022-01-04
3 2022-01-05
4 2022-01-06
5 2022-01-07
استبدال دالة SQL
-- Replace a SQL scalar function.
> CREATE OR REPLACE FUNCTION square(x DOUBLE) RETURNS DOUBLE RETURN x * x;
-- Replace a SQL table function.
> CREATE OR REPLACE FUNCTION getemps(deptno INT)
RETURNS TABLE (name STRING)
RETURN SELECT name FROM employee e WHERE e.deptno = getemps.deptno;
-- Describe a SQL table function.
> DESCRIBE FUNCTION getemps;
Function: default.getemps
Type: TABLE
Input: deptno INT
Returns: id INT
name STRING
إشعار
لا يمكنك استبدال دالة موجودة بتوقيع مختلف.
وصف دالة SQL
> DESCRIBE FUNCTION hello;
Function: hello
Type: SCALAR
Input: ()
Returns: STRING
> DESCRIBE FUNCTION area;
Function: default.area
Type: SCALAR
Input: x DOUBLE
y DOUBLE
Returns: DOUBLE
> DESCRIBE FUNCTION roll_dice;
Function: default.roll_dice
Type: SCALAR
Input: num_dice INT
num_sides INT
Returns: INT
> DESCRIBE FUNCTION EXTENDED roll_dice;
Function: default.roll_dice
Type: SCALAR
Input: num_dice INT DEFAULT 1 'number of dice to roll (Default: 1)'
num_sides INT DEFAULT 6 'number of sides per dice (Default: 6)'
Returns: INT
Comment: Roll a number of m-sided dice
Deterministic: false
Data Access: CONTAINS SQL
Configs: ...
Owner: the.house@always.wins
Create Time: Sat Feb 12 09:29:02 PST 2022
Body: aggregate(sequence(1, roll_dice.num_dice, 1),
0,
(acc, x) -> (rand() * roll_dice.num_sides)::int,
acc -> acc + roll_dice.num_dice)
إنشاء وظائف Python
—- Hello World-like functionality using Python UDFs
> CREATE FUNCTION main.default.greet(s STRING)
RETURNS STRING
LANGUAGE PYTHON
AS $$
def greet(name):
return "Hello " + name + "!"
return greet(s) if s else None
$$
—- Can import functions from std library and environment
> CREATE FUNCTION main.default.isleapyear(year INT)
RETURNS BOOLEAN
LANGUAGE PYTHON
AS $$
import calendar
return calendar.isleap(year) if year else None
$$
—- Must return the correct type. Otherwise will fail at runtime.
> CREATE FUNCTION main.default.a_number()
RETURNS INTEGER
LANGUAGE PYTHON
AS $$
# does not work: return "10"
# does not work: return 3.14
return 10
$$
—- Deal with exceptions.
> CREATE FUNCTION main.default.custom_divide(n1 INT, n2 INT)
RETURNS FLOAT
LANGUAGE PYTHON
AS $$
try:
return n1/n2
except ZeroDivisionException:
# in case of 0, we can return NULL.
return None
$$