How to use output parameters with stored procedures and data adapters
Posted: Tue 26 Feb 2008 01:02
Hi,
I am having trouble calling a postgres stored procedure (via a table adapter) using input and output parameters. Here is my code:
I get this exception:
My database table create script:
My stored procedure create script:
Note that when I comment out the following line, I don't get an error (but I also fail to get the id_cds value populated into my datatable):
Can you please tell me how I can fix this issue so that the output parameter id_cds is populated into the id_cds row of my dataset?
Thanks
Phoebe
I am having trouble calling a postgres stored procedure (via a table adapter) using input and output parameters. Here is my code:
Code: Select all
PgSqlConnectionStringBuilder connBuilder = new PgSqlConnectionStringBuilder();
connBuilder.Database = "sharpy";
connBuilder.Host = "bjdev01";
connBuilder.Password = "password";
connBuilder.Port = 5432;
connBuilder.Protocol = ProtocolVersion.Ver30;
connBuilder.Schema = "sharpy";
connBuilder.UserId = "sharpy";
PgSqlConnection conn = new PgSqlConnection(connBuilder.ConnectionString);
PgSqlDataAdapter adp = new PgSqlDataAdapter();
adp.InsertCommand = new PgSqlCommand();
adp.InsertCommand.CommandText = "usp_cds_i";
adp.InsertCommand.CommandType = System.Data.CommandType.StoredProcedure;
adp.InsertCommand.Connection = conn;
adp.InsertCommand.Parameters.Add(new PgSqlParameter(":name_cds", PgSqlType.VarChar, 0, System.Data.ParameterDirection.Input, false, ((byte)(0)), ((byte)(0)), "name_cds", System.Data.DataRowVersion.Current, null));
adp.InsertCommand.Parameters.Add(new PgSqlParameter(":id_cds", PgSqlType.BigInt.ToString(), ParameterDirection.Output, false, "id_cds", DataRowVersion.Current, null));
adp.InsertCommand.UpdatedRowSource = System.Data.UpdateRowSource.OutputParameters;
adp.UpdateBatchSize = 1000; // This is important, I do not want to have a batch size of 1 because I am working with thousands of rows
PgSqlDataTable dt = new PgSqlDataTable("select * from sharpy.cds", conn);
dt.Columns.Add("id_cds", typeof(long));
dt.Columns.Add("name_cds", typeof(string));
System.Data.DataRow row = dt.NewRow();
row["name_cds"] = "test_" + new Random().Next();
dt.Rows.Add(row);
// Do the update with the data adapter. This throws exception.
// We want it to populate the id_cds value into the data row.
conn.Open();
try
{
adp.Update(dt);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
conn.Close();
conn.Dispose();
}
Code: Select all
[System.ArgumentOutOfRangeException]: {"Parameter name is missing.\r\nParameter name: id_cds"}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
InnerException: null
Message: "Parameter name is missing.\r\nParameter name: id_cds"
Source: "System.Data"
StackTrace: " at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)\r\n at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)\r\n at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)\r\n at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping)\r\n at System.Data.Common.DbDataAdapter.Update(DataTable dataTable)\r\n at DBUtilities.OutputParametersProblem.TestOutputParameters() in C:\dev\trunk\gui\common\DBUtilities\DBUtilities_NUnit\OutputParametersProblem.cs:line 46"
TargetSite: {Int32 UpdatedRowStatusErrors(System.Data.Common.RowUpdatedEventArgs, BatchCommandInfo[], Int32)}
Code: Select all
CREATE TABLE sharpy.cds
(
id_cds bigint NOT NULL DEFAULT nextval('sharpy.seq_cds'::regclass),
name_cds character varying(50) NOT NULL,
CONSTRAINT pk_id_cds PRIMARY KEY (id_cds)
)
WITHOUT OIDS;
Code: Select all
CREATE OR REPLACE FUNCTION sharpy.usp_cds_i(IN character varying, OUT bigint) AS
$BODY$
INSERT INTO sharpy.cds (name_cds) VALUES ($1);
SELECT currval('sharpy.seq_cds') as id_cds;
$BODY$
LANGUAGE 'sql' VOLATILE;
Code: Select all
adp.InsertCommand.Parameters.Add(new PgSqlParameter(":id_cds", PgSqlType.BigInt.ToString(), ParameterDirection.Output, false, "id_cds", DataRowVersion.Current, null));
Thanks
Phoebe