【发布时间】:2021-04-26 08:50:18
【问题描述】:
我正在从 SQL Server 迁移到 PostgreSQL,并且我在 SQL Server 中有以下存储过程和函数。
ALTER FUNCTION [dbo].[GetContainsSafeText] (@text nvarchar(250))
RETURNS nvarchar(250)
AS
BEGIN
SET @text = ISNULL(NULLIF(ISNULL(@text, ''), ''), '""');
SET @text = TRIM(@text);
WHILE (CHARINDEX(' ', @text) > 0)
SET @text = REPLACE(@text, ' ', ' ');
SET @text = REPLACE(@text, ' ', ' AND ');
RETURN @text;
END
ALTER PROCEDURE [dbo].[SearchGroupQuery]
@skip int,
@count int,
@text nvarchar(250),
@from datetime2,
@location uniqueidentifier,
@category uniqueidentifier,
@geoLocation geography
AS
BEGIN
SET NOCOUNT ON;
SET @text = dbo.GetContainsSafeText(@text);
WITH LocationTree AS
(
SELECT Id, ParentId
FROM Locations
WHERE Id = @location
UNION ALL
SELECT Locations.Id, Locations.ParentId
FROM LocationTree
JOIN Locations ON LocationTree.Id = Locations.ParentId
)
SELECT *
FROM [groups] g
WHERE (@text = '""' OR
CONTAINS([Description], @text) OR
CONTAINS([Title], @text) OR
Id IN (SELECT GroupId
FROM [Events]
WHERE [Time] >= @from
AND (CONTAINS([Description], @text) OR
CONTAINS([Title], @text))
))
AND (@location IS NULL OR LocationId IN (SELECT Id FROM LocationTree))
AND (@category IS NULL OR Id IN (SELECT GroupId FROM [GroupCategories] cg
WHERE cg.CategoryId = @category))
ORDER BY
Title
OFFSET @skip ROWS FETCH NEXT @count ROWS ONLY;
END
我已将它们迁移到以下位置,但我遇到了control reached end of function without RETURN。我找到了this question,但接受的答案对我没有帮助。这让我想知道SQL 或PL/pgSQL 哪个更好。我发现accepted answer here 很有趣。如果我理解正确,我不能使用SQL,但问题是我怎样才能使以下内容变得更好?另外,添加return query 并没有解决我的问题。
CREATE OR REPLACE FUNCTION GetContainsSafeText(p_text char varying(250))
RETURNS char varying(250)
AS $$
BEGIN
p_text := coalesce(nullif(coalesce(p_text, ''), ''), '""');
p_text := trim(p_text);
while(POSITION(' ' IN p_text) > 0) loop
p_text := replace(p_text, ' ', ' ');
END Loop;
p_text := replace(p_text, ' ', ' & ');
RETURN p_text;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION SearchGroupQuery (
p_skip int,
p_count int,
p_text char varying(250),
p_from timestamp(6),
p_location char varying(36),
p_category char varying(36),
p_geoLocation geography)
RETURNS setof "Groups" AS $$
BEGIN
p_text := GetContainsSafeText(p_text);
return query --<< this was missing the first time
with recursive LocationTree
as
(
select "Id", "ParentId" from "Locations" where "Id" = p_location
union all
select "Locations"."Id", "Locations"."ParentId" from LocationTree t join "Locations" on t."Id" = "Locations"."ParentId"
)
select
*
from "Groups" g
where
(
p_text = '""""' or
to_tsvector('simple', "Title" || ' ' || "Description") @@ to_tsquery(p_text) or
Id in (
select "GroupId"
from "Events"
where "Time" >= p_from and
to_tsvector('simple', "Title" || ' ' || "Description") @@ to_tsquery(p_text)
)
) and
(
p_location is null or
"LocationId" in (select "Id" from "LocationTree")
) and
(
p_category is null or
"Id" in (
select "GroupId"
from "GroupCategories" cg
where cg."CategoryId" = p_category
)
)
order by "Title"
LIMIT v_count offset p_skip ;
END;
$$ LANGUAGE plpgsql;
【问题讨论】:
-
与您的问题无关,但是:您应该真正避免使用那些可怕的带引号的标识符。他们的麻烦比他们的价值要多得多。 wiki.postgresql.org/wiki/…
-
感谢您的宝贵建议,@a_horse_with_no_name。然后我需要在 ef core 中找到一种简单的方法来为我执行此操作。
标签: sql-server postgresql full-text-search query-optimization database-migration