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 <> '1') AND (paraVIEWFLAG <> '0')) THEN     set SQLCODE_OUT_TMP = -1; END IF;  IF (paraMODIFYFLAG IS NULL) OR ((paraMODIFYFLAG <> '1') AND (paraMODIFYFLAG <> '0')) THEN     SET SQLCODE_OUT_TMP = -2; END IF;  IF (paraADVANCEFLAG IS NULL) OR ((paraADVANCEFLAG <> '1') AND (paraADVANCEFLAG <> '0')) THEN     SET SQLCODE_OUT_TMP = -3; END IF;  IF NOT EXISTS (SELECT *                FROM DMS.CM_STAFF                WHERE STAFFPKID = paraSTAFFID AND STATUS = '10' AND (DELETED IS NULL OR DELETED = '0')) 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 <> '1') AND (paraVIEWFLAG <> '0')) THEN     set SQLCODE_OUT_TMP = -1; END IF;  IF (paraMODIFYFLAG IS NULL) OR ((paraMODIFYFLAG <> '1') AND (paraMODIFYFLAG <> '0')) THEN     SET SQLCODE_OUT_TMP = -2; END IF;  IF (paraADVANCEFLAG IS NULL) OR ((paraADVANCEFLAG <> '1') AND (paraADVANCEFLAG <> '0')) THEN     SET SQLCODE_OUT_TMP = -3; END IF;  IF NOT EXISTS (SELECT *                FROM DMS.CM_STAFF                WHERE STAFFPKID = paraSTAFFID AND STATUS = '10' AND (DELETED IS NULL OR DELETED = '0')) 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;