Column <<column_name>> not found when using ADO-NET connection for Postgresql in insert query - postgresql

I have problem when using ADO.NET connection for PostgreSQL. I have tried this query using PSQLODBC driver 12.000.000 both ANSI and Unicode. I use PostgreSQL v.9.5. I notice the column name has "_" in its name.
When I use the Select query, the connection successfully execute it. The query return variables as I want.
using (OdbcConnection conn = (OdbcConnection)Dts.Connections["XXX"].AcquireConnection(Dts.Transaction))
{
try
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
}
catch (Exception e)
{
String err = e.Message.ToString();
Console.WriteLine(err);
}
try
{
OdbcCommand cmd = new OdbcCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT XX FROM <<table>> where <<params>>";
...
OdbcDataReader rdd = cmd.ExecuteReader();
while (rdd.Read())
{
<<read operation here>>;
}
conn.Close();
}
catch (Exception ers)
{
<<catch operation here>>;
}
}
But when I use Insert query, it failed to check the column name, even the column are exist in my PostgreSQL tables:
using (OdbcConnection conn2 = (OdbcConnection)Dts.Connections["OJK_REPORTING_DEV"].AcquireConnection(Dts.Transaction))
{
try
{
if (conn2.State != ConnectionState.Open)
{
conn2.Open();
}
}
catch (Exception e)
{
string x = e.Message.ToString();
}
try
{
OdbcCommand cmd = new OdbcCommand();
cmd.Connection = conn2;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO <<table>>(<<column>>)VALUES(<<params>>)";
<<cmd.Parameters.AddWithValue here>>;
cmd.ExecuteNonQuery();
conn2.Close();
}
catch (Exception e)
{
<<exception catch here>>;
}
}
When I debug this line, I get this error:
ERROR[42703] ERROR: column <> not found, error while executing the query

Right, after several research, I've got an answer. Since i use PostgreSQL ODBC, the query parameters are not using #<name> inside the query, but using ?, so you need to formulate the query like
INSERT INTO <TABLE_NAME> (<COLUMNS>) VALUE ?
and call the parameters
cmd.AddWithValue("#<name>",<value>)

Related

Apply migration on multiple schemas using Java and Liquibase

I'm trying to apply migration over my multi tenant system where I have one database with multiple schemas,
And I do so by first getting all the tenants then loop over them and execute the update on liquibase after changing the schema, but it seems that the schema is not changed cause after performing the migration on the first tenant the second tenant throws an error complaining about table already exist.
#Override
#SneakyThrows
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
Connection connection = null;
Statement statement = null;
Liquibase liquibase = null;
try {
connection = dataSource.getConnection();
statement = connection.createStatement();
ResultSet result = statement.executeQuery("SELECT nspname FROM pg_namespace WHERE nspname like 'tenant_%'");
List<String> schemas = new ArrayList<>();
while (result.next()) {
schemas.add(result.getString(1));
}
for (String schemaName:schemas) {
connection.setSchema(schemaName);
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
database.setDefaultSchemaName(schemaName);
log.info("Schema Name: {}",connection.getSchema());
liquibase = new Liquibase(CHANGE_LOG_FILE, new ClassLoaderResourceAccessor(), database);
liquibase.update(new Contexts(), new LabelExpression());
}
} catch (SQLException | DatabaseException e) {
e.printStackTrace();
}finally {
if(liquibase!=null) {
liquibase.close();
}
if(statement!=null&&!statement.isClosed()) {
statement.close();
}
if(connection!=null&&!connection.isClosed()){
connection.close();
}
}
}
Note: the reason I made it in different loops and not using `try-with-resource` is that the connection closes after getting the first row of the result set and updating the database so I had to close it myself

CachedRowSet always returns empty

public CachedRowSet execute(String asql) throws ServiceUnavailableException {
try (Connection connection = getDatabaseConnection();
Statement statement = connection.createStatement();) {
try (ResultSet resultSet = statement.executeQuery(asql);
CachedRowSet rowset = CachedRowSetFactory.getCachedRowSet()) {
rowset.populate(resultSet);
return rowset;
}
} catch (SQLException se) {
throw new ServiceUnavailableException("Database broken " + se);
} catch (Exception ne) {
throw new ServiceUnavailableException("JNDI Lookup broken ");
}
return null;
}
Hi everyone. I have a sample code as above. The problem is that returned rowset is always empty, even though there are lots of data in database.
Any suggestions? Thank you.

SQL increment id, filling first line of database

I habe a sqlite database in java (eclipse) with the library sqlite-jdbc-3.16.1.jar.
I have 5 rows in table1: id(ID Integer PRIMARY KEY AUTOINCREMENT), name, row3, row4, row5
I want to insert name, row3 and row4 and the id to increment itself.
public static void insertTest(String name, byte[] contentRow3, byte[] contentRow4) {
String sql = "INSERT INTO table1(name, contentRow3, contentRow4) VALUES(?,?,?)";
try (Connection conn = connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(2, name);
pstmt.setBytes(3, contentRow3);
pstmt.setBytes(4, contentRow4);
System.out.println("Added new Person to DB");
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
Error : Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
What is the problem here?
Placeholders in Java prepared statements begin at index 1, not 2. I expect that the following corrected code should work:
try (Connection conn = connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, name);
pstmt.setBytes(2, contentRow3);
pstmt.setBytes(3, contentRow4);
System.out.println("Added new Person to DB");
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
The exception you are getting is complaining that index position 3 is out of bounds. Most likely, under the hood when you did pstmt.setBytes(3, contentRow4) this translated to accessing the fourth array element, which would be index 3 assuming the array indexing is zero based.

In what order C# execute sqlstatement?

I have two table related by foreign and primary key constraint.The Visit_Number in Patient table must exist in the Visit table.In my code in define create two instance of my connection string such that i can use one instance to insert record:VisitNumber in Visit table first and then the other instance to insert record in the patient table,with the believe that the cord runs from top to bottom.But this was n't the case. i still get foreign key constraint errror:
Error Number:547
Error MessageThe INSERT statement conflicted with the FOREIGN KEY constraint "Patient_Vist_FK".
The conflict occurred in database "TestDB", table "dbo.Visit", column 'Visit_Number'.
The statement has been terminated.On line Number: 1
meaning the code is running as i expected. Please do you have a better approach and why isn't mine working
code:
protected void btn_save_Click(object sender, EventArgs e)
{
string connect = System.Configuration.ConfigurationManager.ConnectionStrings["db_connection"].ToString();
SqlConnection con = new SqlConnection(connect);
SqlConnection con2 = new SqlConnection(connect);
string visitnumber = txtVistNumber.Text.ToString();
string insert_statement = "Insert into Patient(Patient_Number,FirstName,LastName,Gender,Tribe,Date_Of_Birth,Visit_Number)"
+ "Values(#Patient_Number,#FirstName,#LastName,#Gender,#Tribe,#Date_Of_Birth,#Visit_Number)";
string insert_stament2 = "Insert into Visit(Visit_Number)"
+ "Values(#Visit_Number)";
SqlCommand cmd = new SqlCommand(insert_statement, con);
SqlCommand cmd2 = new SqlCommand(insert_stament2, con2);
cmd2.Parameters.AddWithValue("#Visit_Number", txtVistNumber.Text);
cmd.Parameters.AddWithValue("#Patient_Number",txtpatientNum.Text);
cmd.Parameters.AddWithValue("#FirstName",txtfirstName.Text);
cmd.Parameters.AddWithValue("#LastName",txtlastname.Text);
cmd.Parameters.AddWithValue("#Gender", drl_gender.SelectedValue);
cmd.Parameters.AddWithValue("#Tribe",DropDownList1.Text);
cmd.Parameters.AddWithValue("#Date_Of_Birth", val_age.Text);
cmd.Parameters.AddWithValue("#Visit_Number", txtVistNumber.Text);
try
{
using (con)
{
con.Open();
int count = cmd.ExecuteNonQuery();
if (count > 0)
{
Response.Write("<script language=javascript>alert('Record Sucessfully Inserted!');</script>");
//Success_Message.Text = "Record inserted";
txtpatientNum.Text = String.Empty;
txtfirstName.Text = String.Empty;
txtlastname.Text = String.Empty;
txtVistNumber.Text = String.Empty;
DropDownList1.Text = String.Empty;
val_age.Text = String.Empty;
}
}
}
catch (SqlException ex)
{
{
VisitError_Message.Text = "Error Number:" + ex.Number.ToString() + " Error Message" + ex.Message + "On line Number" + ": " + ex.LineNumber;
}
}
catch (NullReferenceException nullexception)
{
VisitError_Message.Text = "Error Occurred, Error Type:" + nullexception.GetType().ToString() + "Error Message:" + nullexception.Message;
}
catch (DllNotFoundException dllexception)
{
VisitError_Message.Text = dllexception.GetType().ToString() + dllexception.Message;
}
finally
{
con.Close();
}
}
you not excuting you cmd2, you must execute the insert Visit_Number in cmd2 then excute your cmd, you can test this code
using (con2)
{
con2.Open();
cmd2.ExecuteNonQuery();
}
then you can excute your cmd
using (con)
{
con.Open();
int count = cmd.ExecuteNonQuery();
}
and you can do the work with the same connexion if you want
string connect = System.Configuration.ConfigurationManager.ConnectionStrings["db_connection"].ToString();
SqlConnection con = new SqlConnection(connect);
string visitnumber = txtVistNumber.Text.ToString();
string insert_statement = "Insert into Patient(Patient_Number,FirstName,LastName,Gender,Tribe,Date_Of_Birth,Visit_Number)"
+ "Values(#Patient_Number,#FirstName,#LastName,#Gender,#Tribe,#Date_Of_Birth,#Visit_Number)";
string insert_stament2 = "Insert into Visit(Visit_Number)"
+ "Values(#Visit_Number)";
using(con)
{
con.open;
SqlCommand cmd2 = new SqlCommand(insert_stament2, con);
cmd2.Parameters.AddWithValue("#Visit_Number", txtVistNumber.Text);
cmd2.ExecuteNonQuery();
SqlCommand cmd = new SqlCommand(insert_statement, con);
cmd.Parameters.AddWithValue("#Visit_Number", txtVistNumber.Text);
cmd.Parameters.AddWithValue("#Patient_Number",txtpatientNum.Text);
cmd.Parameters.AddWithValue("#FirstName",txtfirstName.Text);
cmd.Parameters.AddWithValue("#LastName",txtlastname.Text);
cmd.Parameters.AddWithValue("#Gender", drl_gender.SelectedValue);
cmd.Parameters.AddWithValue("#Tribe",DropDownList1.Text);
cmd.Parameters.AddWithValue("#Date_Of_Birth", val_age.Text);
cmd.Parameters.AddWithValue("#Visit_Number", txtVistNumber.Text);
cmd.ExecuteNonQuery();
}

How update DB table with DataSet

I am begginer with ADO.NET , I try update table with DataSet.
O client side I have dataset with one table. I send this dataset on service side (it is ASP.NET Web Service).
On Service side I try update table in database, but it dont 't work.
public bool Update(DataSet ds)
{
SqlConnection conn = null;
SqlDataAdapter da = null;
SqlCommand cmd = null;
try
{
string sql = "UPDATE * FROM Tab1";
string connStr = WebConfigurationManager.ConnectionStrings["Employees"].ConnectionString;
conn = new SqlConnection(connStr);
conn.Open();
cmd=new SqlCommand(sql,conn);
da = new SqlDataAdapter(sql, conn);
da.UpdateCommand = cmd;
da.Update(ds.Tables[0]);
return true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (conn != null)
conn.Close();
if (da != null)
da.Dispose();
}
}
Where can be problem?
It is better to look how really ADO.Net dataset works.
http://support.microsoft.com/kb/308507