Writing queries for a PostgreSQL DB - c#

To start, here's what I got so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npgsql; // Npgsql .NET Data Provider for PostgreSQL
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
NpgsqlConnection conn = new NpgsqlConnection ("Server=127.0.0.1;Port=5432;UserId=postgres;Password=test;Database=dbab;") ;
conn.Open() ;
// Define a query
NpgsqlCommand cmd = new NpgsqlCommand("set schema 'data'; select test_run.id from test_run;", conn);
cmd.ExecuteNonQuery();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(reader.GetString(0));
}
}
// Close connection
conn.Close();
System.Console.WriteLine("Press any key to close...");
Console.ReadKey();
}
}
}
Whenever I run this, I get NpgsqlException was unhandled. Under that it says:
An unhandled exception of type 'Npgsql.NpgsqlException' occurred in Npgsql.dll
Additional information: External component has thrown an exception.
When I click view detail, this shows: {"42P01: relation \"test_run\" does not exist"}
When I saw this, I thought maybe my query somehow messed up, but it actually is fine because I ran it in pgAdmin with no problems finding 'test_run' table.
I installed Npgsql -Version 3.0.5 and Mono.Security 3.2.3.0 with Nuget. I also added to two .dll's (not sure how to check this) into the GAC.
In addition, I uninstalled Npgsql, installed it again, but instead got version 2.2.3, and still ran into the same problem. I'm now back with version 3.0.5.
I'm not sure how to fix this, please help.
EDIT:
As jackmott said, I needed to split up the queries. Here's what I did:
NpgsqlCommand cmd = new NpgsqlCommand("set schema 'data';", conn);
cmd.ExecuteNonQuery();
NpgsqlCommand cmd2 = new NpgsqlCommand("select test_run.id from test_run;", conn);
cmd2.ExecuteNonQuery();
And it works.

instead of set schema try:
set search_path to 'schema'
Which is what set schema should alias to, but perhaps that alias doesn't work in NpgSQL
The other thing I would try is to run the set search_path as it's own command, then run the query as the next command..
Third thing to check, is if the user has permissions to read that table in that schema.

Related

.Net Core - SQL Server Geography data type exception

I am trying to use the new Microsoft.Data.SqlClient in my .Net Core application. Whenever I select a column that has a datatype of Geography, I get the following error.
Unable to cast object of type 'Microsoft.SqlServer.Types.SqlGeography' to type 'Microsoft.Data.SqlClient.Server.IBinarySerialize'.'
To reproduce, I created a database on my computer (SQL2019) with one table:
DROP TABLE IF EXISTS geotest
GO
CREATE TABLE geotest (g GEOGRAPHY)
GO
INSERT INTO geotest (g)
VALUES
( 0xe6100000010cec51b81e854b4040ec51b81e852b58c0 ),
( 0xe6100000010c6666666666a64740713d0ad7a3905ec0 )
I create a console application project (Visual Studio 2019, .Net Core 3.1) and add the NUGET package: Microsoft.Data.SqlClient
Here is my sample app:
using System;
using Microsoft.Data.SqlClient;
namespace TestWithOtherSQL
{
class Program
{
static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("Data Source=localhost;Initial Catalog=joe;Trusted_Connection=True;");
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = #"SELECT g FROM geotest";
SqlDataReader sr = cmd.ExecuteReader();
while (sr.Read())
{
var a = sr[0];
}
conn.Close();
Console.WriteLine("Hello World!");
}
}
}
It throws the error on this line:
var a = sr[0];
Unable to cast object of type 'Microsoft.SqlServer.Types.SqlGeography' to type 'Microsoft.Data.SqlClient.Server.IBinarySerialize'.'
Troubleshooting:
If I change out the Nuget package to System.Data.SqlClient and include package Microsoft.SqlServer.Types (change the using to System.Data.SqlClient) The same code works.
So why don't I just do that? Good question... My actual database is on Azure SQL DB and I need to use Microsoft.Data.SqlClient to support ActiveDirectory Password Authentication (that does not work with System.Data.SqlClient) - but that's a different issue....
Also Microsoft.Data.SqlClient is the "new" ".NetCore" way of doing things. Not a huge issue for me right now, but not sure if that would work if we ported to Linux are tried to run in an Azure function.

I need to connect with Remote Database from Xamarin application [duplicate]

I'm having trouble with my code to access a MySQL Database. Everytime I try to open my connection, a System.TypeInitializationException is thrown by MySql.Data.MySqlClient.Replication.ReplicationManager. Here is my code:
DataTable results = new DataTable("Results");
using (MySqlConnection connection = new MySqlConnection("SERVER=127.0.0.1;DATABASE=foo;UID=bar;PASSWORD=foobar;"))
{
using (MySqlCommand command = new MySqlCommand(queryString, connection))
{
command.Connection.Open(); //throws System.TypeInitializationException
command.ExecuteNonQuery();
using (MySqlDataReader reader = command.ExecuteReader())
results.Load(reader);
}
}
Edit: I guess MySQL Driver was corrupt. After an upgrade from Windows 7 to Windows 10 everything worked fine.
I had the same problem but when i installed the MySql.Data.dll using Nuget then the problem is solved
Install MySql.Dll file from Nuget,
not from MySQL Website.
Your connection string format is wrong. Try this :
static string cs = #"server=localhost;user id=bar;password=foobar;database=foo;";
DataTable results = new DataTable("Results");
using (MySqlConnection connection = new MySqlConnection(cs))
{
using (MySqlCommand command = new MySqlCommand(queryString, connection))
{
command.Connection.Open(); //throws System.TypeInitializationException
command.ExecuteNonQuery();
using (MySqlDataReader reader = command.ExecuteReader())
results.Load(reader);
}
}
In my case, it raised error only in production. It was due to a wrong assumption in the MySql.Data package. It for some reason seems to demand to be in the same folder as the orchestrating dll (it was referencing another dll which was referencing MySql). I resolved my issue by removing MySql.Data and instead installing MySqlConnector package as suggested in here.

C# - unable to connect to a local ACCDB file with new SqlConnection()

Doing a university project that requires an application that stores and outputs data from a local access DB file.
So far I have very little C# knowledge but I have a basic understanding of how to write code and what functions and methods are.
I have looked up a lot of different questions on StackOverflow and other sites about this kind of issue, yet I could not find a solution to my problem.
Here is the code -
private void search_db(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection())
{
string search_query = search_input.Text;
conn.ConnectionString = "Data Source=D:/Projects/WIP/8515/Academy/Travel Agency C#/Hotel_Agency/Hotel_Database.accdb;";
conn.Open();
SqlCommand command = new SqlCommand("SELECT * FROM Customers WHERE (name LIKE #query) OR (EGN LIKE #query)", conn);
command.Parameters.Add(new SqlParameter("query", search_query));
// Create new SqlDataReader object and read data from the command.
using (SqlDataReader reader = command.ExecuteReader())
{
// while there is another record present
while (reader.Read())
{
// write the data on to the screen
Console.WriteLine(String.Format("{0} \t | {1} \t | {2} \t | {3}",
// call the objects from their index
reader[0], reader[1], reader[2], reader[3]));
}
}
}
}
on line 6 of the given code, if my ConnectionString which provides the data souce which I have triple checked and confirmed is proper, the only thing I'm not sure is what type of slash should I use, since the default \ slash from windows directories gets mistaken for an escape by Visual Studio, while with the / slash its ok.
The problem is the connection to the DB always fails with this error
An unhandled exception of type 'System.Data.SqlClient.SqlException'
occurred in System.Data.dll
Additional information: A network-related or instance-specific error
occurred while establishing a connection to SQL Server. The server was
not found or was not accessible. Verify that the instance name is
correct and that SQL
Here is the full list of the namespaces we are using for this application
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
I have tried adding provider keyword to the connection string but that leads to another error about an unsupported keyword, since the System.Data.SqlClient namespace is allegedly automatically setting a provider.
Any help as to what might be causing this is appreciated!
PS: I apologize for any further lack of knowledge I present, I really am new to C# programming, but I find it quite interesting and exciting, and would like to learn more.
You are making a common mistake here. The classes defined in the namespace System.Data.SqlClient (SqlConnection, SqlCommand etc.) are able to talk only with a Sql Server database system (Full, Express or LocalDb). They cannot work with an Access database.
For this database you should use the classes in the System.Data.OleDb namespace (OleDbConnection, OleDbCommand etc.) These classes understand the connectionstring to reach an Access database and can open and work with it.
So your code should be:
....
using System.Data.OleDb;
private void search_db(object sender, EventArgs e)
{
using (OleDbConnection conn = new OleDbConnection())
{
conn.ConnectionString = ......
conn.Open();
string cmdText = #"SELECT *
FROM Customers
WHERE ([name] LIKE #q1) OR (EGN LIKE #q2)";
using(OleDbCommand command = new OleDbCommand(cmdText, conn))
{
command.Parameters.Add("#q1", OleDbType.VarWChar).Value = search_query;
command.Parameters.Add("#q2", OleDbType.VarWChar).Value = search_query;
using (OleDbDataReader reader = command.ExecuteReader())
{
....
}
}
}
}
An importat thing to remember with OleDb is that you have positional parameters. The parameters are not recognized by their name but by their position in the query text. So if you have two parameters placeholder, even if they are for the same value, you need to put two parameters in the collection. One for the first placeholder and one for the second placeholder. This is even more important when you have placeholders for different values. You need to add the values in the exact order in which they are expected in the query text.

Error "ORA-00933: SQL command not properly ended" on Select with ODBC Command

I'm trying to execute a query against an Oracle DB using ODBC in .NET and am getting the following error:
ORA-00933: SQL command not properly ended
However, the SQL statement is definitely correct, and I can execute it successfully from Oracle SQL Developer. The query itself looks like this:
SELECT * FROM TABLE(SCHEMA.PKG.SPNAME('PARAMS'));
Another simple query works fine:
SELECT COUNT(*) FROM SCHEMA.MYTABLE
It looks like something with the former, where it's using a package in the query and causing something to break. The error indicates that it's not properly ended, but it has a semi-colon and correct braces, so it seems something else is going on.
If I remove the trailing semi-colon, I get an error with no message.
My C# code is basic and looks like this:
using (var connection = new OdbcConnection(connectionString))
{
using (var command = connection.CreateCommand())
{
command.CommandText = commandText;
connection.Open();
var result = command.ExecuteScalar();
connection.Close();
Console.WriteLine(result);
}
}
When using the Oracle library for .NET, it works when I remove the trailing semi-colon. If I keep that in place, the same error about the SQL command not being properly ended comes up.
It seems like this query should work with ODBC. Is there anything I need to differently to get it working, or is using the Oracle Managed Data Provider the only way?
From my experience, I have noticed several instances where a semicolon will break the query, such as JasperSoft Studio and the cx_Oracle Python module. I know very little about ODBC vs OracleDataClient, but I would imagine this is a similar situation.
I would not use ODBC I would actually do something like this using the OracleDataClient
var strSQL = "SELECT * FROM TABLE(SCHEMA.PKG.SPNAME('PARAMS'));";
using (OracleConnection connStr = new OracleConnection(connectionString))
{
using (OracleCommand cmd = new OracleCommand(strSQL, connStr))
{
cmd.CommandType = CommandType.Text;
cmd.Connection.Open();
cmd.ExecuteScalar(); //change the ExecuteScalar to fit the proper call
}
}

What is the best way to connect and use a sqlite database from C#

I've done this before in C++ by including sqlite.h but is there a similarly easy way in C#?
I'm with, Bruce. I AM using http://system.data.sqlite.org/ with great success as well. Here's a simple class example that I created:
using System;
using System.Text;
using System.Data;
using System.Data.SQLite;
namespace MySqlLite
{
class DataClass
{
private SQLiteConnection sqlite;
public DataClass()
{
//This part killed me in the beginning. I was specifying "DataSource"
//instead of "Data Source"
sqlite = new SQLiteConnection("Data Source=/path/to/file.db");
}
public DataTable selectQuery(string query)
{
SQLiteDataAdapter ad;
DataTable dt = new DataTable();
try
{
SQLiteCommand cmd;
sqlite.Open(); //Initiate connection to the db
cmd = sqlite.CreateCommand();
cmd.CommandText = query; //set the passed query
ad = new SQLiteDataAdapter(cmd);
ad.Fill(dt); //fill the datasource
}
catch(SQLiteException ex)
{
//Add your exception code here.
}
sqlite.Close();
return dt;
}
}
There is also an NuGet package: System.Data.SQLite available.
Microsoft.Data.Sqlite by Microsoft has over 9000 downloads every day, so I think you are safe using that one.
Example usage from the documentation:
using (var connection = new SqliteConnection("Data Source=hello.db"))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText =
#"
SELECT name
FROM user
WHERE id = $id
";
command.Parameters.AddWithValue("$id", id);
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var name = reader.GetString(0);
Console.WriteLine($"Hello, {name}!");
}
}
}
I've used this with great success:
http://system.data.sqlite.org/
Free with no restrictions.
(Note from review: Original site no longer exists. The above link has a link pointing the the 404 site and has all the info of the original)
--Bruce
There is a list of Sqlite wrappers for .Net at http://www.sqlite.org/cvstrac/wiki?p=SqliteWrappers. From what I've heard http://sqlite.phxsoftware.com/ is quite good. This particular one lets you access Sqlite through ADO.Net just like any other database.
There's also now this option: http://code.google.com/p/csharp-sqlite/ - a complete port of SQLite to C#.
https://github.com/praeclarum/sqlite-net is now probably the best option.
Another way of using SQLite database in NET Framework is to use Fluent-NHibernate.
[It is NET module which wraps around NHibernate (ORM module - Object Relational Mapping) and allows to configure NHibernate programmatically (without XML files) with the fluent pattern.]
Here is the brief 'Getting started' description how to do this in C# step by step:
https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started
It includes a source code as an Visual Studio project.
Here I am trying to help you do the job step by step: (this may be the answer to other questions)
Go to this address , down the page you can see something like "List of Release Packages". Based on your system and .net framework version choose the right one for you. for example if your want to use .NET Framework 4.6 on a 64-bit Windows, choose this version and download it.
Then install the file somewhere on your hard drive, just like any other software.
Open Visual studio and your project. Then in solution explorer, right-click on "References" and choose "add Reference...".
Click the browse button and choose where you install the previous file and go to .../bin/System.Data.SQLite.dll and click add and then OK buttons.
that is pretty much it. now you can use SQLite in your project.
to use it in your project on the code level you may use this below example code:
make a connection string:
string connectionString = #"URI=file:{the location of your sqlite database}";
establish a sqlite connection:
SQLiteConnection theConnection = new SQLiteConnection(connectionString );
open the connection:
theConnection.Open();
create a sqlite command:
SQLiteCommand cmd = new SQLiteCommand(theConnection);
Make a command text, or better said your SQLite statement:
cmd.CommandText = "INSERT INTO table_name(col1, col2) VALUES(val1, val2)";
Execute the command
cmd.ExecuteNonQuery();
that is it.
Mono comes with a wrapper, use theirs!
https://github.com/mono/mono/tree/master/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0 gives code to wrap the actual SQLite dll ( http://www.sqlite.org/sqlite-shell-win32-x86-3071300.zip found on the download page http://www.sqlite.org/download.html/ ) in a .net friendly way. It works on Linux or Windows.
This seems the thinnest of all worlds, minimizing your dependence on third party libraries. If I had to do this project from scratch, this is the way I would do it.
if you have any problem with the library you can use Microsoft.Data.Sqlite;
public static DataTable GetData(string connectionString, string query)
{
DataTable dt = new DataTable();
Microsoft.Data.Sqlite.SqliteConnection connection;
Microsoft.Data.Sqlite.SqliteCommand command;
connection = new Microsoft.Data.Sqlite.SqliteConnection("Data Source= YOU_PATH_BD.sqlite");
try
{
connection.Open();
command = new Microsoft.Data.Sqlite.SqliteCommand(query, connection);
dt.Load(command.ExecuteReader());
connection.Close();
}
catch
{
}
return dt;
}
you can add NuGet Package Microsoft.Data.Sqlite

Categories

Resources