urlencode مع وظائف فقط المدمج في
-
19-08-2019 - |
سؤال
ودون استخدام plpgsql، وأنا أحاول أن urlencode نص معين داخل عبارة SELECT pgsql.
والمشكلة مع هذا النهج:
select regexp_replace('héllo there','([^A-Za-z0-9])','%' || encode(E'\\1','hex'),'g')
... هو أن وظيفة تشفير لا يتم تمرير المعلمة التعبير العادي، ما لم تكن هناك طريقة أخرى لاستدعاء وظائف من داخل التعبير استبدال أن يعمل فعلا. لذلك أنا أتساءل عما اذا كان هناك تعبير البديلة والتي، في حد ذاته، ويمكن تشفير المباريات في القيم عرافة.
وربما تكون هناك مجموعات أخرى من الوظائف. اعتقد انه سيكون هناك التعابير المنطقية ذكي (والتي قد تكون لا تزال الجواب) هناك، ولكن أواجه صعوبة في العثور عليه.
المحلول
select regexp_replace(encode('héllo there','hex'),'(..)',E'%\\1','g');
وهذا لا يترك أحرف أبجدية رقمية الإنسان للقراءة، وإن كان.
نصائح أخرى
وهنا وظيفة كتبت أن مقابض الترميز باستخدام بنيت في وظائف مع الحفاظ على سهولة قراءة URL.
والتعبيرات المنتظمة مباريات لالتقاط أزواج من (اختياري) الأحرف آمنة وحرف (واحد على الأكثر) غير آمن. يختار المتداخلة تسمح تلك أزواج أن يكون ترميز وإعادة الجمع بين العائدين سلسلة المشفرة بالكامل.
ولقد شغلت من خلال مجموعة الاختبار مع جميع أنواع التباديل (الرائدة / زائدة / فقط / تكرار الحروف المشفرة وحتى الآن يبدو أن ترميز بشكل صحيح.
والأحرف الخاصة الآمنة هي _ ~. - و/. بلدي إدراج "/" في تلك القائمة هو ربما غير القياسية، ولكن يناسب حالة استخدام لدي حيث إدخال النص قد يكون المسار وأريد أن البقاء.
CREATE OR REPLACE FUNCTION oseberg.encode_uri(input text)
RETURNS text
LANGUAGE plpgsql
IMMUTABLE STRICT
AS $function$
DECLARE
parsed text;
safePattern text;
BEGIN
safePattern = 'a-zA-Z0-9_~/\-\.';
IF input ~ ('[^' || safePattern || ']') THEN
SELECT STRING_AGG(fragment, '')
INTO parsed
FROM (
SELECT prefix || encoded AS fragment
FROM (
SELECT COALESCE(match[1], '') AS prefix,
COALESCE('%' || encode(match[2]::bytea, 'hex'), '') AS encoded
FROM (
SELECT regexp_matches(
input,
'([' || safePattern || ']*)([^' || safePattern || '])?',
'g') AS match
) matches
) parsed
) fragments;
RETURN parsed;
ELSE
RETURN input;
END IF;
END;
$function$
وهنا هو مقطع صغير جدا، وانها حتى وظيفة "SQL النقي"، وليس plpgsql. يتم دعم أحرف متعددة البايت (بما في ذلك 3- و 4 بايت التعبيرية).
create or replace function urlencode(in_str text, OUT _result text) returns text as $$
select
string_agg(
case
when ol>1 or ch !~ '[0-9a-za-z:/@._?#-]+'
then regexp_replace(upper(substring(ch::bytea::text, 3)), '(..)', E'%\\1', 'g')
else ch
end,
''
)
from (
select ch, octet_length(ch) as ol
from regexp_split_to_table($1, '') as ch
) as s;
$$ language sql immutable strict;
ويمكنك استخدام CLR واستيراد مساحة الاسم أو استخدام وظيفة هو موضح في هذا الرابط، وهذا يخلق وظيفة T-SQL التي لا الترميز.
http://www.sqljunkies.com /WebLog/peter_debetta/archive/2007/03/09/28987.aspx