I cant get reliable checking for database existence in NET/Npgsql at my program startup.
Here is code:
Public Function dbExists(ByVal _dbName As String) As Boolean
Dim retval As Boolean = False
Using mCon As New NpgsqlConnection(String.Format( _
"Server={0};Port={1};User Id={2};Password={3};", _
dbserver, dbport, "postgres", dbpass))
Try
mCon.Open()
Using nCom = New NpgsqlCommand("SELECT 1 FROM pg_database WHERE datname='" + _dbName + "'", mCon)
retval = CBool(nCom.ExecuteScalar())
End Using
Catch ex As Exception
retval = False
End Try
End Using
Return retval
End Function
This function return True no matter database exists or not.
I also try with null checking on ExecuteScalar, getting Count(*) and all what I can without better result.
What to do to get it working?
Null checking on 'ExecuteScalar()' works for me (PostgreSQL 9.3 and Npgsql 2.0.12).
Are you checking 'ExecuteScalar() == null'?
ExecuteScalar will return a .NET null not DBNull.Value (since it is not a record with a null value, it signifies no matching result).
I'm not a VB person but here's how I achieved it in C#:
bool dbExists;
using (NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;Database=postgres;User Id=postgres;Password=testpass"))
{
conn.Open();
string cmdText = "SELECT 1 FROM pg_database WHERE datname='temp'";
using (NpgsqlCommand cmd = new NpgsqlCommand(cmdText, conn))
{
dbExists = cmd.ExecuteScalar() != null;
}
}
Related
I tried to call my user defined function in pgresql from C# code,
my function creation script is as follows,
CREATE OR REPLACE FUNCTION public."GetUserDailyData"(
cid integer,
hid integer,
currday integer)
RETURNS character varying AS
$BODY$
DECLARE
returndata varchar = '';
BEGIN
SELECT data->20+currday into returndata FROM pops
WHERE hybid = hid and cropid = cid;
return returndata;
END
$BODY$
LANGUAGE plpgsql
COST 100;
My method to call this function is as follows,
public static object ExecuteScalar(string conString, string spName, NpgsqlParameter[] param)
{
using (var conn = new NpgsqlConnection(conString))
{
conn.Open();
using (var tran = conn.BeginTransaction())
using (var command = conn.CreateCommand())
{
command.CommandText = spName;
command.CommandType = CommandType.StoredProcedure;
for (var i = 0; i < param.Length; i++)
{
command.Parameters.Add(new NpgsqlParameter());
command.Parameters[i] = param[i];
}
var result = command.ExecuteScalar();
return result;
}
}
}
I tried everything even checked the existence of this function in pg_proc using
select * from pg_proc where proname = 'GetUserDailyData'
and it reflected the function details row.
But every time it is giving the same error.
Any kind of suggestion would be highly appreciated. Thanks.
Adding objects with case sensitive names in PostgreSQL can lead to these complications; in this case you need to specify the name of the stored procedure between quotes, however it would be advisable to simply not create any objects that rely on case sensitivity, use underscores instead, or when create/refer to objects using CamelCase without the quotes (which creates/refers to the objects in low-caps). In any case, you may also need to specify the whole interface (not just the name) as the CommandText, and specify the data types of the parameters (see this).
...
command.CommandText = "\"" + spName + "\"";
...
I have now facing the problem in bytea to Base64, actually I have save the image in below query,
user_profile_pic is defind in bytea in table
Update user_profile_pic
Set user_profile_pic = (profilepic::bytea)
Where userid = userid;
after that I have select the below query,
case 1:
SELECT user_profile_pic
FROM user_profile_pic;
its return exact same as I have updated, but after passing service its display a byte format
case 2:
Select encode(user_profile_pic::bytea, 'base64')
FROM user_profile_pic;
it returns totally different result.
I want to result case 1 along with service?
its working for me, not working query if write procedure/function, i write direct code behind
conn.Open();
NpgsqlCommand command = new NpgsqlCommand("SELECT profile_pic FROM userlog WHERE cust_id = '" + CustID + "'", conn);
Byte[] result = (Byte[])command.ExecuteScalar();
if(result.Length > 0)
{
ProfilePicture = Convert.ToBase64String(result);
ErrorNumber = 0;
ErrorMessage = "Successful operation";
}
else
{
ErrorNumber = 1;
}
conn.Close();
I am using NpgSQL with PostgreSQL and ADO.NET. Forgive the simplicity of the question as I just started using PostgreSQL and NpgSQL this week.
Something like this works fine:
[Test]
public void InsertNoParameters()
{
NpgsqlConnection conn = new NpgsqlConnection("Host=localhost; Database=postgres; User ID=postgres; Password=password");
conn.Open();
IDbCommand command = conn.CreateCommand();
string sql = "INSERT INTO Customers (FirstName,LastName) VALUES ('Test','Tube')";
command.CommandText = sql;
command.ExecuteNonQuery();
conn.Close();
}
When I put in parameters I get the error message:
Npgsql.NpgsqlException : ERROR: 42703: column "_firstname" does not exist
[Test]
public void InsertWithParameters()
{
NpgsqlConnection conn = new NpgsqlConnection("Host=localhost; Database=postgres; User ID=postgres; Password=password");
conn.Open();
IDbCommand command = conn.CreateCommand();
string sql = "INSERT INTO Customers (FirstName,LastName) VALUES (_FirstName,_LastName)";
command.CommandText = sql;
var parameter = command.CreateParameter();
parameter.ParameterName = "_FirstName";
parameter.Value = "Test";
command.Parameters.Add(parameter);
parameter = command.CreateParameter();
parameter.ParameterName = "_LastName";
parameter.Value = "Tube";
command.Parameters.Add(parameter);
command.ExecuteNonQuery();
conn.Close();
}
The responses in the comments are correct:
Npgsql doesn't support _ as a parameter placeholder notation. You should be using # or : (so #FirstName or :FirstName, not _FirstName).
PostgreSQL will automatically lower-case your table and column names unless they are double-quoted. Either use lower-case names for everything (simpler) or quote identifiers in your SQL queries.
So your code should look more or less like this:
IDbCommand command = conn.CreateCommand();
string sql = "INSERT INTO Customers (first_name, last_name) VALUES (#FirstName,#LastName)";
command.CommandText = sql;
var parameter = command.CreateParameter();
parameter.ParameterName = "FirstName";
parameter.Value = "Test";
command.Parameters.Add(parameter);
//Class UserProfileDBUtil.java
Connection conn = null;
PreparedStatement statment = null;
ResultSet rs = null;
try{
String sqlString = "select count(*) from "+AGENCY_SCHEMA_NAME+".AGENCY WHERE AGENCYCODE= ? and ENABLEDFLAG = ?";
conn = JDBCUtils.getConnection(JDBCUtils.WP_ODS);
statment = conn.prepareStatement(sqlString);
statment.setString(1, agencyCode.toUpperCase());
statment.setString(2, "Y");
rs =statment.executeQuery(); // SQL Error Line 42
while(rs.next())
{
if(rs.getInt(1) > 0 )
{
return true;
}
}
log.error("Agency for agency code "+agencyCode+" is not available or not active");
}
LOG :
com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -401, SQLSTATE: 42818, SQLERRMC: =
at com.ibm.db2.jcc.b.sf.e(sf.java:1680)
at com.ibm.db2.jcc.b.sf.a(sf.java:1239)
at com.ibm.db2.jcc.c.jb.h(jb.java:139)
at com.ibm.db2.jcc.c.jb.a(jb.java:43)
at com.ibm.db2.jcc.c.w.a(w.java:30)
at com.ibm.db2.jcc.c.cc.g(cc.java:161)
at com.ibm.db2.jcc.b.sf.n(sf.java:1219)
at com.ibm.db2.jcc.b.tf.gb(tf.java:1818)
at com.ibm.db2.jcc.b.tf.d(tf.java:2294)
at com.ibm.db2.jcc.b.tf.X(tf.java:508)
at com.ibm.db2.jcc.b.tf.executeQuery(tf.java:491)
at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.executeQuery(WSJdbcPreparedStatement.java:559)
at UserProfileDBUtil.isAgencyActive(UserProfileDBUtil.java:42)
The error you're getting is a -401, which means:
The data types of the operands for the operation operator are not
compatible or comparable.
I would check and make sure that the parameters you're passing in are using the right data types. If you catch the exception, you should be able to use the exceptions Message property to see what the operator is. See here for an example.
I have a simple function that just inserts the parameter values provided to it into columns in a table.
When I run the function via the ExecuteNonQuery() method on the command object I always get -1, even if the insert took place.
If i run the same query as a Text command it gives be the correct result of 1.
I'm new to postgresql/npgsql. Is there trick to making the function feed back the number of rows affected? Something like "set nocount off" in SQL Server?
EDIT:
The code I am using: (with npgsql 2.0.11)
var connStr = #"Server=127.0.0.1;Port=5432;User Id=postgres;Password=***;Database=Test;";
using (var conn = new NpgsqlConnection(connStr)) {
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "insert_something";
cmd.CommandType = CommandType.StoredProcedure;
NpgsqlCommandBuilder.DeriveParameters(cmd);
cmd.Parameters["_id"].Value = 1;
cmd.Parameters["_val"].Value = 2;
var rowsAffected = cmd.ExecuteNonQuery();
Console.WriteLine(rowsAffected);
}
}
I haven't used Npgsql, but the documentation has an example with
the following code:
NpgsqlCommand command = new NpgsqlCommand("insert into table1 values(1, 1)", conn);
Int32 rowsaffected;
try
{
rowsaffected = command.ExecuteNonQuery();
}
If you are talking about some PostgreSQL function like this:
CREATE FUNCTION myinsert(integer) RETURNS void
LANGUAGE 'sql' AS 'INSERT INTO mytable VALUES ($1)';
and you are doing something like SELECT myinsert(1);, you can't get the number of affected rows, because you are running a SELECT and what the function does internally is opaque to you.
For ExecuteNonQuery() to get the number of rows affected, your postgresql function should return just that. An example would be:
CREATE OR REPLACE FUNCTION insert_something(_id int, _val int)
RETURNS int as $$
DECLARE count int;
BEGIN
INSERT INTO some_table (id, value) VALUES(_id, _val);
GET DIAGNOSTICS count = ROW_COUNT;
RETURN count;
END;
$$ language plpgsql;
Now if you call ExecuteNonQuery() from your code, you should get the inserted rows count.
Here's how I have implemented and its working for me without any issues:
Add an OUT Parameter to your function.
CREATE OR REPLACE FUNCTION schema.UpdateSomeValue(
IN par_updateId text,
OUT par_returnvalue INT4)
BEGIN
UPDATE schema.TableToUpdate
SET status = 1
WHERE ID = par_updateId;
GET DIAGNOSTICS par_returnvalue = ROW_COUNT;
END;
Now on the C# side
private int UpdateSomeValue()
{
var connStr = #"Server=127.0.0.1;Port=5432;UserId=postgres;Password=***;Database=Test;";
int result = -1;
using (var conn = new NpgsqlConnection(connStr)) {
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "shema.UpdateSomeValue";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("par_updateId",NpgsqlTypes.NpgsqlDbType.INT, 1);
NpgsqlParameter outParm = new NpgsqlParameter("par_returnvalue",
NpgsqlTypes.NpgsqlDbType.Integer)
{
Direction = ParameterDirection.Output
};
cmd.ExecuteNonQuery();
result = Convert.ToInt32(outParm.Value);
}
}
return result;
}
PS : I tried the just ExecuteNonQuery() approach but it was always returning -1 for me (as if no rows has been affected NpgsqlDocumentation) Using above way I was able to capture the Number of rows affected from the PostgreSQL function and with OUT parameter it was easy to catch the affected rows on the client side.