解决postgresql -- ERROR: 42601: query has no destination for result data

时间:2023-03-09 09:08:32
解决postgresql  -- ERROR: 42601: query has no destination for result data

I am learning Npgsql and PostgreSQL. I am unable to define the output parameter correctly. What am I doing wrong?

Here is the function:

CREATE OR REPLACE FUNCTION Insert_Customer_WithOutputParameter(
IN _FirstName character varying DEFAULT NULL::character varying,
IN _LastName character varying DEFAULT NULL::character varying,
OUT _CustomerID integer)
RETURNS integer as
$BODY$
BEGIN
INSERT INTO Customers (FirstName, LastName) VALUES (_FirstName, _LastName); SELECT _CustomerID = lastval(); END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

Here is the code:

[Test]
public void ExecuteNonQuerySproc()
{
NpgsqlConnection conn = new NpgsqlConnection("Host=localhost; Database=postgres; User ID=postgres; Password=password");
conn.Open();
IDbCommand command = conn.CreateCommand();
command.CommandText = "Insert_Customer_WithOutputParameter";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new NpgsqlParameter("@FirstName", "John"));
command.Parameters.Add(new NpgsqlParameter("@LastName", "Smith"));
NpgsqlParameter outParm = new NpgsqlParameter("@CustomerID", NpgsqlDbType.Integer)
{
Direction = ParameterDirection.Output
};
command.Parameters.Add(outParm); command.ExecuteNonQuery();
conn.Close();
Console.WriteLine(outParm.Value);
}

Here is the error message I am getting: Npgsql.NpgsqlException : ERROR: 42601: query has no destination for result data

The following doesn't work:

SELECT _CustomerID = lastval();

Replace it with a simple:

_CustomerID = lastval();

Note that Npgsql currently binds parameters by position only, and not by name. This means that the names you give in the NpgsqlParameter instances mean nothing - their order of addition must correspond to the function's declaration. Npgsql 3.1 will support named binding of function arguments (see this issue).

修改前:

-- Function: sp_updatesecurity(integer, character, character, character, character, integer, integer, character, integer)

-- DROP FUNCTION sp_updatesecurity(integer, character, character, character, character, integer, integer, character, integer);

CREATE OR REPLACE FUNCTION sp_updatesecurity(
OUT sqlcode_out integer,
IN parastaffid integer,
IN parafunctioncode character,
IN paraviewflag character,
IN paramodifyflag character,
IN paraadvanceflag character,
IN paralocalversion integer,
IN original_staffid integer,
IN original_functioncode character,
IN original_localversion integer)
RETURNS integer AS
$BODY$
DECLARE SQLCODE_OUT_TMP INT DEFAULT 0;
begin
IF (paraVIEWFLAG IS NULL) OR ((paraVIEWFLAG <> '') AND (paraVIEWFLAG <> '')) THEN
set SQLCODE_OUT_TMP = -1;
END IF; IF (paraMODIFYFLAG IS NULL) OR ((paraMODIFYFLAG <> '') AND (paraMODIFYFLAG <> '')) THEN
SET SQLCODE_OUT_TMP = -2;
END IF; IF (paraADVANCEFLAG IS NULL) OR ((paraADVANCEFLAG <> '') AND (paraADVANCEFLAG <> '')) THEN
SET SQLCODE_OUT_TMP = -3;
END IF; IF NOT EXISTS (SELECT *
FROM DMS.CM_STAFF
WHERE STAFFPKID = paraSTAFFID AND STATUS = '' AND (DELETED IS NULL OR DELETED = '')) THEN
SET SQLCODE_OUT_TMP = -4;
END IF; IF NOT EXISTS (SELECT *
FROM DMS.MM_FUNCTION
WHERE FUNCTIONCODE = paraFUNCTIONCODE ) THEN
SET SQLCODE_OUT_TMP = -5;
END IF; UPDATE DMS.MM_SECURITY
SET STAFFID = paraSTAFFID
, FUNCTIONCODE = paraFUNCTIONCODE
, VIEWFLAG = paraVIEWFLAG
, MODIFYFLAG = paraMODIFYFLAG
, ADVANCEFLAG = paraADVANCEFLAG
, INPUTTIME = CURRENT_TIMESTAMP
, LOCALVERSION = LOCALVERSION + 1
WHERE (STAFFID = original_STAFFID) AND (FUNCTIONCODE = original_FUNCTIONCODE) AND (LOCALVERSION = original_LOCALVERSION);
SELECT LOCALVERSION INTO paraLOCALVERSION FROM MM_SECURITY
WHERE (STAFFID = paraSTAFFID) AND (FUNCTIONCODE = paraFUNCTIONCODE);
SELECT SQLCODE_OUT_TMP; end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION sp_updatesecurity(integer, character, character, character, character, integer, integer, character, integer)
OWNER TO postgres;

修改后:

-- Function: sp_updatesecurity(integer, character, character, character, character, integer, integer, character, integer)

-- DROP FUNCTION sp_updatesecurity(integer, character, character, character, character, integer, integer, character, integer);

CREATE OR REPLACE FUNCTION sp_updatesecurity(
OUT sqlcode_out integer,
IN parastaffid integer,
IN parafunctioncode character,
IN paraviewflag character,
IN paramodifyflag character,
IN paraadvanceflag character,
IN paralocalversion integer,
IN original_staffid integer,
IN original_functioncode character,
IN original_localversion integer)
RETURNS integer AS
$BODY$
DECLARE SQLCODE_OUT_TMP INT DEFAULT 0;
begin
IF (paraVIEWFLAG IS NULL) OR ((paraVIEWFLAG <> '') AND (paraVIEWFLAG <> '')) THEN
set SQLCODE_OUT_TMP = -1;
END IF; IF (paraMODIFYFLAG IS NULL) OR ((paraMODIFYFLAG <> '') AND (paraMODIFYFLAG <> '')) THEN
SET SQLCODE_OUT_TMP = -2;
END IF; IF (paraADVANCEFLAG IS NULL) OR ((paraADVANCEFLAG <> '') AND (paraADVANCEFLAG <> '')) THEN
SET SQLCODE_OUT_TMP = -3;
END IF; IF NOT EXISTS (SELECT *
FROM DMS.CM_STAFF
WHERE STAFFPKID = paraSTAFFID AND STATUS = '' AND (DELETED IS NULL OR DELETED = '')) THEN
SET SQLCODE_OUT_TMP = -4;
END IF; IF NOT EXISTS (SELECT *
FROM DMS.MM_FUNCTION
WHERE FUNCTIONCODE = paraFUNCTIONCODE ) THEN
SET SQLCODE_OUT_TMP = -5;
END IF; UPDATE DMS.MM_SECURITY
SET STAFFID = paraSTAFFID
, FUNCTIONCODE = paraFUNCTIONCODE
, VIEWFLAG = paraVIEWFLAG
, MODIFYFLAG = paraMODIFYFLAG
, ADVANCEFLAG = paraADVANCEFLAG
, INPUTTIME = CURRENT_TIMESTAMP
, LOCALVERSION = LOCALVERSION + 1
WHERE (STAFFID = original_STAFFID) AND (FUNCTIONCODE = original_FUNCTIONCODE) AND (LOCALVERSION = original_LOCALVERSION);
SELECT LOCALVERSION INTO paraLOCALVERSION FROM MM_SECURITY
WHERE (STAFFID = paraSTAFFID) AND (FUNCTIONCODE = paraFUNCTIONCODE);
sqlcode_out = SQLCODE_OUT_TMP; end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION sp_updatesecurity(integer, character, character, character, character, integer, integer, character, integer)
OWNER TO postgres;