簡體   English   中英

在PostgreSQL上通過聲明變量選擇查詢

[英]Select query by declare variable on postgresql

我是新工作的postgresql和pgadmin4。我寫了一個非常簡單的查詢。

我在公共模式下有一個名為PgFinalLocationsTable的表。在我的表中有一些文件,其中一個是UserName 。我想聲明一個變量,最后根據這個變量在我的表上進行選擇,如下所示:

DO $$
DECLARE myvar text default 'sa';
BEGIN
    select * from public."PgFinalLocationsTable" where "UserName" = myvar;
END $$;

但是為什么我得到這些信息:

ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function inline_code_block line 4 at SQL statement
SQL state: 42601

這是一個簡單的查詢!!!

谷歌搜索並查看堆棧上的帖子后,我更改了查詢,如下所示:

CREATE OR REPLACE FUNCTION fun(text myvar) RETURNS text AS $$
--DECLARE myvar text;
BEGIN
    select * from public."PgFinalLocationsTable" where "UserName" = myvar;
END;
$$ language plpgsql;

select fun('sa'); 

我想返回我的所有字段,並且我不想使用plpgsql 。我想使用PostgreSQL。 無論如何我都遇到了這個錯誤:

ERROR:  type myvar does not exist
SQL state: 42704

我的第一個查詢和第二個查詢有什么問題?當我要傳遞變量時,是否應該為選擇查詢創建函數?

我做了所有事情,因為我想創建此sql查詢:

"IF (NOT EXISTS(SELECT 1 FROM [dbo].[{0}] WHERE [UserId] = @UserId And [DeviceId] = @DeviceId)) " +
"BEGIN " +
"INSERT INTO [dbo].[{0}]([Id], [Location], [Timestamp], [UserId], [DeviceId], [AllowDomains], [Topic], [UserName], [FirstName], [LastName], [JobLocationName], [LocationId], [AppVersion], [AppName]) " +
"VALUES(@Id, GEOGRAPHY::Point(@X, @Y, 4326), @Timestamp, @UserId, @DeviceId, @AllowDomains, @Topic, @UserName, @FirstName, @LastName, @JobLocationName,  @LocationId,  @AppVersion, @AppName) " +
"END "

你不明白DO命令很好。 DO命令是不帶聲明的匿名函數,因為它沒有聲明輸出,所以除調試流之外不可能有其他結果。

因此您的第一個示例在PostgreSQL中沒有意義。 作為MS SQL過程的結果,返回MSSQL中未綁定查詢的結果。 PostgreSQL中不可能有類似的東西。 PostgreSQL只知道可以返回標量值,復合值或關系(僅一個)的函數。 當您從MS SQL中獲得最大的收益時,請嘗試忘記MS SQL的幾乎所有知識。

ERROR:  type myvar does not exist
SQL state: 42704

此錯誤很干凈-您可以切換變量名和類型名-實際上不存在myvar類型。

返回表的一些函數如下所示:

CREATE OR REPLACE FUNCTION fx1(myvar text)
RETURNS SETOF public."PgFinalLocationsTable" AS $$
BEGIN
  RETURN QUERY SELECT * FROM public."PgFinalLocationsTable" WHERE "UserName" = myvar;
END;
$$ LANGUAGE plpgsql;

或者您只能使用SQL語言

CREATE OR REPLACE FUNCTION fx1(myvar text)
RETURNS SETOF public."PgFinalLocationsTable" AS $$
  SELECT * FROM public."PgFinalLocationsTable" WHERE "UserName" = $1;
$$ LANGUAGE sql;

因為PostgreSQL不支持取消綁定查詢,所以不允許它。 您應該使用PLPGSQL語言中的RETURN QUERY命令。

因為在PostgreSQL和MSSQL之間,使用存儲過程進行編程實際上是有區別的(MSSQL與其他SQL不相似),請嘗試閱讀文檔-不錯https://www.postgresql.org/docs/current/static/plpgsql html的

您的函數可以在Postgres中看起來像(我不知道使用的類型)

CREATE OR REPLACE FUNCTION fx("_UserId" int,
                              "_DeviceId" int,
                              "_X" int,
                              "_Y" int, 
                              ...
BEGIN
  IF NOT EXISTS(SELECT * FROM /* I don't know what [{0}] means */
                 WHERE "UserId" = "_UserId" AND "DeviceId" = "_DeviceId")
  THEN
    INSERT INTO ..
  END IF;
END;
$$ LANGUAGE plpgsql;

可能無需INSERT INTO ON CONFLICT DO NOTHING程序擴展就可以通過INSERT INTO ON CONFLICT DO NOTHING命令https://www.postgresql.org/docs/current/static/sql-insert.html來解決您的片段,這是更好的選擇。

注意-使用區分大小寫的標識符是通向地獄的捷徑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM