I have a sqlite database. When I query the db directly via the command line, the schema_version result is 3078.
But when I do this in .NET, the result is always '1'.
Here's a snippet:
public static long GetInternalSchemaVersion(this SQLiteConnection con)
{
using (var cmd = con.CreateCommand())
{
cmd.CommandText = string.Format("PRAGMA schema_version;");
DataTable results;
using (results = new DataTable())
{
using (SQLiteDataAdapter da = new SQLiteDataAdapter(cmd))
{
da.Fill(results);
return results.ToEnumerable().First().GetInt32("schema_version");
}
}
}
}
Am I doing something wrong?
Ideally you would show the connection string you're using. The most likely case is that when you're connecting via .Net, you're not connecting to the same database. The schema version is auto-incremented by SQLite on schema change, so the fact that it's returning 1 suggests this is a new database. To verify, run another query to pull back some other data you expect to be there. You'll probably find that the db is empty.
Related
I want to load millions of records from an Oracle table into a Postgres table in the quickest and most convenient way using a C# console app. Ideally I don't want to COPY out to a .CSV file and then load back in as I am not sure about the necessary permissions on the target server. Is it possible to do it via an Oracle datareader? This is what I have tried so far (The SQL query columns names are named as such to show the datatypes in Oracle)
public void RunExportPackage()
{
var sql = "SELECT NUMBER(10,0), CHAR(3), VARCHAR2(10), NUMBER, CHAR(1) FROM TABLE";
using var sourceConnection = new OracleConnection(_appSettingsOptions.ConnectionStrings.OracleConnection);
OracleCommand com = new OracleCommand(sql, sourceConnection);
sourceConnection.Open();
using (OracleDataReader oracleReader = com.ExecuteReader())
{
using (NpgsqlConnection targetConnection = new NpgsqlConnection(_appSettingsOptions.ConnectionStrings.PostgresConnectionDEV))
{
targetConnection.Open();
using (var writer = targetConnection.BeginBinaryImport("COPY TABLE FROM STDIN BINARY"))
{
writer.WriteRow(oracleReader);
}
}
}
}
When I try this I am getting this error.
IEnumerable parameters are not supported, pass an array or List instead
The column types in the postgres table are
If someone could just point me in the right direction that would be great :)
I have a custom method that handles calls to SQL which takes in a script and a list of SqlParamaters, executes the SQL and then fills a DataSet with any results via SqlDataAdapter. This has been in use for over 3 years on various projects without issue.
Here is a code snippet of how the custom method is called (the actual SQL script is stored in a file):
using (SQLClass _sql = new SQLClass(_Config.DatabaseInfo))
{
FileInfo _file = new FileInfo("\\scripts\\GetEmployeeTable.sql");
List<SqlParameter> _sqlParams = new List<SqlParameter>();
// Convert DateTime to Decimal
_sqlParams.Add(new SqlParameter("PERIODEND", DateToDecimal(periodEnd)));
_sql.ExecuteSqlCommandScript(_file, _sqlParams);
}
private Decimal DateToDecimal(DateTime myDate)
{
Decimal _periodEndDecimal;
String _periodEndString = myDate.ToString("yyyyMMdd");
if (Decimal.TryParse(_periodEndString, out _periodEndDecimal))
return _periodEndDecimal;
return 0;
}
Here is the custom method:
ExecuteSqlCommandScript(FileInfo file, List<SqlParams> sqlParams)
{
. . . (get _sqlScript by reading info from 'file')
. . . (setup SqlConnection info)
using (SqlConnection _conn = new SqlConnection(connectionString))
{
using (SqlCommand _cmd = new SqlCommand())
{
_cmd.CommandText = sqlScript;
_cmd.Connection = _conn;
_cmd.Connection.Open();
// add SqlParameters to SQL command
if (sqlParams != null)
{
_cmd.Parameters.AddRange(sqlParams.ToArray());
}
using (SqlDataAdapter _sqlDataAdapter = new SqlDataAdapter(_cmd))
{
try
{
// Save Table info to Results object
DataSet _dataSet = new DataSet();
_sqlDataAdapter.Fill(_dataSet); <!-- program falls into catch block here
SqlResult _result = new SqlResult();
_result.DataSet = _dataSet;
_result.TableCount = _dataSet.Tables.Count;
this.Results.Add(_result);
}
}
}
}
}
I am now updating an older project to use this method to query an employee table which stores dates as Decimal type (i.e., 12/25/2016 is stored in SQL as 21061225). This is a table from another company/product that we integrate with, so I CANNOT change this column to DateTime.
Here is the script I am executing:
SELECT ch.EMPLOYEE
FROM UPCHKH ch
WHERE ch.PEREND = #PERIODEND
The older code used SqlDataReader to retrieve the results and this script would execute successfully. When I run this script using our custom procedure (using SqlDataAdapter), I get this error:
ERROR: Arithmetic overflow error converting expression to data type
datetime.
I traced this call though SQL Server Profiler and this is the actual call to SQL:
exec sp_executesql N'
SELECT ch.EMPLOYEE
FROM UPCHKH ch
WHERE
ch.PEREND = #PERIODEND
',N'#PERIODEND decimal(8,0)',#PERIODEND=20161101
If I copy this exact script to a SQL window and run it, I get the expected results.
So, is SqlDataAdapter doing something funky to the SQL call or the results that are coming back from SQL? The custom method above is failing on the line identified. We are using .NET 4.5 and SQL 2014 in case that matters.
I am new to C# and have been using PHP for Years.
The problem I am facing is that I want to create a method/function that will take an "sql query" as parameter and return whatever data is retrieved so that it can be used using the key/index/column_name.
What I have achieved
I have achieved is that I am able to access the data through index within the same function.
but I wont know the no. of columns that will return so I am unable to store it in an array.
Code
string ConnectionString = ConfigurationManager.ConnectionStrings["sqlcon"].ConnectionString;
MySqlConnection db;
db = new MySql.Data.MySqlClient.MySqlConnection(ConnectionString);
try
{
db.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = db;
cmd.CommandText = sql;
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr['areaId'].toString());
}
db.Close();
return true;
}
The problems
1. I do not know the number of Columns.
2. I cannot access the index or Column name.
I want to create an associative array of data with the column name as index and data as its data
EDIT
I am trying to build an application on C# using WPF with MySQL Database.
My first suggestion would be to use one of the micro ORMs like Dapper.net
This can be fetched via nuget. If you wish to retrieve an unknown array of data from a table, or number of tables, you could fetch it into an ExpandoObject and then enumerate over that. An example of looping over an ExpandoObject can be found here.
public Foo FetchSomeData(string query)
{
using (var cn = Connection)
{
var result = cn.Query(query);
//do something with result, and return it
return new Foo(result);
}
}
I'd have concerns about passing raw sql into the DB without at least checking it or using parameters as it could be a major security risk, especially if you allow users to generate the query and you don't vet it first.
I have a sqlite database consist of 50 columns and more than 1.2 million rows. I'm using System.Data.Sqlite to work with Visual Studio 2013 C# language.
I used a very simple code to retrieve my data from database but it is taking too much time.
private SQLiteConnection sqlite;
public MySqlite(string path)
{
sqlite = new SQLiteConnection("Data Source="+path+"\\DBName.sqlite");
}
public DataTable selectQuery(string query)
{
SQLiteDataAdapter ad;
DataTable dt = new DataTable();
try
{
SQLiteCommand cmd;
sqlite.Open();
cmd = sqlite.CreateCommand();
cmd.CommandText = query; //set the passed query
ad = new SQLiteDataAdapter(cmd);
ad.Fill(dt); //fill the datasource
}
catch (SQLiteException ex)
{
//exception code here.
}
sqlite.Close();
return dt;
}
And, the select statement is:
select * from table
As I told you, it is a very simple code.
I want to know how to boost select operation performance to get the appropriate result. for this code the process takes up to 1 minute which I want to get to less than 1 second.
and another thing is that there seems to be some tags for configuring sqlite database but I don't know where to apply them. could some one tell me how to configure sqlite database with System.Data.Sqlite;
Consider narrowing your result set by getting necessary columns or paging.
I have an asp.net project done in C# (my C# syntax is very rusty) and am using the built in database it creates with the project. I've created a table called aspnet_Tutorials that (for now) stores two columns of user submitted data: TutorialName and TutorialContent. Very simple, it's a learning project.
What I need to do is create a list from the first column of aspnet_Tutorials to use it to create a "directory" of the tutorials on a page. The part I'm having trouble with, mostly syntactically, is connecting to and iterating over the column to get the values into a list. Could anyone provide a straight forward example of this? And possibly explain what's going on in the code.
public class TutorialsDirDAL
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString);
SqlCommand cmd = new SqlCommand();
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
public List<string> DisplayTutorials() //parameters? String qry?
{
//query the database table, foreach loop over the data, place it into a list?
}
}
I know how to write simple sql queries. But I've seen a couple different set ups for this in my Googling spree. I currently have the following for a query, feel free to pick it apart or offer a better solution than using a query.
cmd.CommandText = "SELECT * FROM ASPNET_TUTORIALS (TutorialTitle)"
+ "VALUES (#tutorialTitle)";
Thank you!
ebad86's answer is acceptable but since you are obviously learning I think introducing OO principals muddy the water with what you are trying to learn at this point.
Here is a basic method:
private void GetData()
{
//The object that will physically connect to the database
using(SqlConnection cnx = new SqlConnection("<your connection string>")
{
//The SQL you want to execute
SqlCommand cmd = new SqlCommand("SELECT * FROM ASPNET_TUTORIALS");
//Open the connection to the database
cnx.Open();
//execute your command
using (IDataReader dataReader = cnx.ExecuteReader(cmd))
{
//Loop through your results
while(dataReader.Read())
{
//do whatever to the data
ListItem item = new ListItem(Convert.ToString(dataReader["TutorialName"]));
lst.Items.Add(item);
}
}
}
}
This is all very straightforward. The part you are most interested in is the while loop though. The loop will go through all of the returned records and you can do whatever you need to do with them. In my example I have assumed that there is a ListBox named 'lst' and I am simply adding ListItems to it that will have the name of whatever 'TutorialName' is. You can make literally do whatever you need to do with the data at this point. To fit your example (returning a List) you would do this:
private List<string> GetData()
{
List<string> lst = new List<string>();
//The object that will physically connect to the database
using(SqlConnection cnx = new SqlConnection("<your connection string>")
{
//The SQL you want to execute
SqlCommand cmd = new SqlCommand("SELECT * FROM ASPNET_TUTORIALS");
//Open the connection to the database
cnx.Open();
//execute your command
using (IDataReader dataReader = cnx.ExecuteReader(cmd))
{
//Loop through your results
while(dataReader.Read())
{
lst.Add(Convert.ToString(dataReader["TutorialName"]));
}
}
}
return lst;
}
Please respond if you have any questions.
Well you can fetch using data reader and map to the object. I can give you some rough code, which could be like this:
using (IDataReader objDataReader = objDB.ExecuteReader(objCMD))
{
while (objDataReader.Read())
{
DataBaseObject obj = new DataBaseObject();
obj = MapObjectToList(objDataReader);
ObjectList.Add(obj);
}
objDataReader.Dispose();
}
// Mapping Function can be called somewhat like this:
private DataBaseObject MapObjectToList(IDataReader objDataReader)
{
DataBaseObject obj = new DataBaseObject();
obj.Prop1Name = base.GetDataValue<string>(objDataReader, "Column1Name");
obj.Prop2Name = base.GetDataValue<string>(objDataReader, "Column2Name");
return obj;
}
But this is just a rough idea how I would do it.