I want to insert data into a row in PostgreSQL from NPGSQL, but there is something wrong with my query string. Can you please suggest modify it?
public IActionResult Create(string item_name, string item_count, string item_size)
{
using var connection = new NpgsqlConnection(connString);
connection.Open();
string query = #"INSERT INTO public.""items""(""item_count"",""item_name"",""item_size"")VALUES ('"+item_count+item_count+item_count+"')";
using var command = new NpgsqlCommand(query, connection);
int result = command.ExecuteNonQuery();
if (result < 0)
{
return Error();
}
return View(nameof(Create));
}
You can do it in this way.
You have forgotten to add "," between the values and also add quotes if the value is string or date.
public IActionResult Create(string item_name, string item_count, string item_size)
{
using var connection = new NpgsqlConnection(connString);
connection.Open();
string query = String.Format(#"INSERT INTO public.""items""(""item_count"",""item_name"",""item_size"")VALUES('{0}','{1}','{2}');" , item_count , item_count ,item_count);
using var command = new NpgsqlCommand(query, connection);
int result = command.ExecuteNonQuery();
if (result < 0)
{
return Error();
}
return View(nameof(Create));
}
Related
I have a table with three columns
MyDate : DateiIme
MyBlob: blob
Id: String
I want to return MyDate and MyBlob as Json. There can be multiple records in the table.
public class MyData
{
public string? MyDate { get; set; };
public string? MyBlob { get; set; };
}
public async Task<string> GetQueryResult(string Id)
{
MyData data = new MyData();
List<MyData> MyList = new List<MyData>();
string sqlSelect = string.Format("Select MyDate, MyBlob from MyTablee WHERE Id = '{0}'", Id);
try
{
MySqlCommand sqlcmd = new MySqlCommand();
MySqlConnection connetcion = new MySqlConnection(connectionString);
sqlcmd.Connection = connetcion;
sqlcmd.CommandTimeout = 0;
sqlcmd.CommandType = CommandType.Text;
sqlcmd.CommandText = sqlSelect;
connetcion.Open();
using (connetcion)
{
int count = 0;
using (MySqlDataReader reader = sqlcmd.ExecuteReader())
{
while (reader.Read())
{
data.MyDate = reader.GetString(0);
data.MyBlob = reader.GetString(1);
MyList.Add(data);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
var json = JsonSerializer.Serialize(results);
return json;
}
The output in the Postman is:
"{\"MyDate\":\"1/30/2023 9:16:40 PM\",\"MyBlob\":\"#MyBlob\"}"
I am not sure the blob data to JSON conversion is correct. Thank you.
It's probable that your table doesn't contain any BLOB data, but instead contains the literal string #MyBlob in that column.
The cause of this would be using a SQL statement like INSERT INTO MyTablee(MyDate, MyBlob) VALUES(NOW, '#MyBlob');, which inserts the literal text #MyBlob.
Make sure your insert code is constructed as follows:
using var command = connection.CreateCommand();
command.CommandText = "INSERT INTO MyTablee(MyDate, MyBlob) VALUES(NOW(), #blob);";
command.Parameters.AddWithValue("#blob", yourBlobDataHere);
command.ExecuteNonQuery();
In particular, there are no quotes around the parameter name in the INSERT statement, and command parameters are being used to send values, instead of string concatenation.
Currently, I am using MVC on creating a project. Now I want to insert an Identity ID value into an INSERT statement.
In my controller:
string payment = #"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount)
VALUES('{0}','{1}',{2})";
int pay = DBUtl.ExecSQL(payment, "Cash", currency,total);
if (pay == 1)
{
string pid = "SELECT TOP 1 Payment_id FROM Payment ORDER BY Payment_id DESC";
int paymentid = DBUtl.ExecSQL(pid);
if (cart.Count() != 0)
{
string order = #"INSERT INTO [Order](Order_Name,Order_Description,Order_Quantity,Payment_Id)
VALUES('{0}','{1}',{2},{3})";
Now, I want to the payment_id that already been inserted into the payment table which is the first statement and retrieve the payment_id and use it into the INSERT statement for the Order table
How can I achieve that?
Please Help
Thank you
Actually, DBUtil code consists of:
public static int ExecSQL(string sql, params object[] list)
{
List<String> escParams = new List<String>();
foreach (object o in list)
{
if (o == null)
escParams.Add("");
else
escParams.Add(EscQuote(o.ToString()));
}
DB_SQL = String.Format(sql, escParams.ToArray());
int rowsAffected = 0;
using (SqlConnection dbConn = new SqlConnection(DB_CONNECTION))
using (SqlCommand dbCmd = dbConn.CreateCommand())
{
try
{
dbConn.Open();
dbCmd.CommandText = DB_SQL;
rowsAffected = dbCmd.ExecuteNonQuery();
}
catch (System.Exception ex)
{
DB_Message = ex.Message;
rowsAffected = -1;
}
}
return rowsAffected;
}
And as you know ExecuteNonQuery denotes the numbers affecting the row
So, You can do as shown below:
FOR SQL SERVER 2005 and above
using (SqlConnection con=new SqlConnection(#"Your connectionString"))
{
using(SqlCommand cmd=new SqlCommand("INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount) output INSERTED.Payment_id VALUES(#Payment_Method,#Currency_Type,#Total_Amount)",con))
{
cmd.Parameters.AddWithValue("#Payment_Method", "Cash");
cmd.Parameters.AddWithValue("#Currency_Type", currency);
cmd.Parameters.AddWithValue("#Total_Amount", total);
con.Open();
int payment_id =Convert.ToInt32(cmd.ExecuteScalar());
if (con.State == System.Data.ConnectionState.Open)
con.Close();
return payment_id ;
}
}
also, you can change your query to:
"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount) VALUES(#Payment_Method,#Currency_Type,#Total_Amount)"; SELECT SCOPE_IDENTITY()"
For now, I tried something like this:
public IActionResult SaveDetail(List<Cart_Has_Services> cart,double total,string currency)
{
string payment = #"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount)
VALUES('{0}','{1}',{2});";
int pay = DBUtl.ExecSQL(payment, "Cash", currency,total);
if (pay == 1)
{
object pid = DBUtl.GetList("SELECT Payment_id FROM Payment");
int paymentid = Convert.ToInt32(pid);
if (cart.Count() != 0)
{
string order = #"INSERT INTO [Order](Order_Name,Order_Description,Order_Quantity,Payment_Id)
VALUES('{0}','{1}',{2},{3})";
foreach (var item in cart)
{
int ord = DBUtl.ExecSQL(order, item.Cart_Service, item.Additional_Notes, item.Quantity,paymentid);
As for now, the codes will run by inserting the values into the payment table. After that, I want to get the payment_id for my next insert which is the order table.
The method that I tried to get the payment_id does not work.
I have a very silly problem. I am doing a select, and I want that when the value comes null, return an empty string. When there is value in sql query, the query occurs all ok, but if there is nothing in the query, I have to give a sqlCommand.CommandTimeout greater than 300, and yet sometimes gives timeout. Have a solution for this?
public string TesteMetodo(string codPess)
{
var vp = new Classe.validaPessoa();
string _connection = vp.conString();
string query = String.Format("SELECT COUNT(*) FROM teste cliente WHERE cod_pess = {0}", codPess);
try
{
using (var conn = new SqlConnection(_connection))
{
conn.Open();
using (var cmd = new SqlCommand(query, conn))
{
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
return "";
return codPess;
}
}
}
You should probably validate in the UI and pass an integer.
You can combine the usings to a single block. A bit easier to read with fewer indents.
Always use parameters to make the query easier to write and avoid Sql Injection. I had to guess at the SqlDbType so, check your database for the actual type.
Don't open the connection until directly before the .Execute. Since you are only retrieving a single value you can use .ExecuteScalar. .ExecuteScalar returns an Object so must be converted to int.
public string TesteMetodo(string codPess)
{
int codPessNum = 0;
if (!Int32.TryParse(codPess, out codPessNum))
return "codPess is not a number";
var vp = new Classe.validaPessoa();
try
{
using (var conn = new SqlConnection(vp.conString))
using (var cmd = new SqlCommand("SELECT COUNT(*) FROM teste cliente WHERE cod_pess = #cod_pess", conn))
{
cmd.Parameters.Add("#cod_pess", SqlDbType.Int).Value = codPessNum;
conn.Open();
int count = (int)cmd.ExecuteScalar();
if (count > 0)
return "";
return codPess;
}
}
catch (Exception ex)
{
return ex.Message;
}
}
I have a method in my controller class that is supposed to return the results from a raw SQL query inside the method. The problem is I can't pull return more than one column result to the list in a query that is supposed to return multiple column results.
I know that the problem has to do with how I am adding to the results list during the Read, but I am unsure how to structure this properly to return multiple values.
Here is my current method:
public IActionResult Search ([FromRoute]string input)
{
string sqlcon = _iconfiguration.GetSection("ConnectionStrings").GetSection("StringName").Value;
List<string> results = new List<string>();
using (var con = new SqlConnection(sqlcon))
{
using (var cmd = new SqlCommand()
{
CommandText = "SELECT u.UserID, u.User FROM [dbo].[Users] u WHERE User = 'Value';",
CommandType = CommandType.Text,
Connection = con
})
{
con.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
results.Add(reader.GetString(0));
}
con.Close();
return Ok(new Search(results));
}
}
}
}
The SQL query is supposed to return the UserID and User based on the entered User, however, only the User gets returned here.
Does anyone know what I am missing to return multiple column names for this SQL query and method? Any advice would be greatly appreciated.
FYI, I can't use a stored procedure here, I do not have permission to create an SP on this database.
You can create a class for the results of the Query
public class ClassForResults(){
public int UserID { get; set; };
public string User { get; set; }
}
public IActionResult Search ([FromRoute]string input)
{
string sqlcon = _iconfiguration.GetSection("ConnectionStrings").GetSection("StringName").Value;
List<ClassForResults> results = new List<ClassForResults>();
using (var con = new SqlConnection(sqlcon))
{
using (var cmd = new SqlCommand()
{
CommandText = "SELECT u.UserID, u.User FROM [dbo].[Users] u WHERE User = 'Value';",
CommandType = CommandType.Text,
Connection = con
})
{
con.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
ClassForResults result = new ClassForResults();
result.UserID = reader.GetInt(0);
result.User = reader.GetString(1);
results.Add(result);
}
con.Close();
return Ok(new Search(results));
}
}
}
}
I am trying to return data using IEnumerable with given fields, where I am calling the the method I want to reference the data with given field name and return that.
Example, here is the function
public IEnumerable<IDataRecord> GetSomeData(string fields, string table, string where = null, int count = 0)
{
string sql = "SELECT #Fields FROM #Table WHERE #Where";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("#Fields", SqlDbType.NVarChar, 255).Value = where;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
Calling:
IEnumerable<IDataRecord> data = bw.GetSomeData("StaffCode, Perms", "BW_Staff", "StaffCode = 'KAA'");
What must I do to return the data this way or what way ?
string staffCode = data["StaffCode"].ToString();
string perms = data["Perms"].ToString();
Thanks for any help
your data variable is a collection of rows. You need to iterate over the collection to do something interesting with each row.
foreach (var row in data)
{
string staffCode = row["StaffCode"].ToString();
string perms = row["Perms"].ToString();
}
Update:
Based on your comment that you only expect GetSomeData(...) to return a single row, I'd suggest 1 of two things.
Change the signature of GetSomeData to return an IDataRecord. and remove "yield" from the implementation.
public IDataRecord GetSomeData(string fields, string table, string where = null, int count = 0)
{
string sql = "SELECT #Fields FROM #Table WHERE #Where";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("#Fields", SqlDbType.NVarChar, 255).Value = where;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
return (IDataRecord)rdr;
}
}
}
}
}
Or
var row = data.FirstOrDefault();
if (row != null)
{
string staffCode = row["StaffCode"].ToString();
string perms = row["Perms"].ToString();
}
Remarks:
Your implementation of GetSomeData is incomplete. You are not even using several of the parameters, most importantly the fields parameter. And conceptually in SQL you can't parameterize which fields get returned or which table gets used (etc.), but rather you need to construct a dynamic query and execute it.
Update 2
Here is an implementation of GetSomeData that constructs a proper query (in C# 6, let me know if you need it in an earlier version).
public IEnumerable<IDataRecord> GetSomeData(IEnumerable<string> fields, string table, string where = null, int count = 0)
{
var predicate = string.IsNullOrWhiteSpace(where) ? "" : " WHERE " + where;
string sql = $"SELECT { string.Join(",", fields) } FROM {table} {predicate}";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
And here is how you would use it.
IEnumerable<IDataRecord> data = bw.GetSomeData(new[] { "StaffCode", "Perms" }, "BW_Staff", "StaffCode = 'KAA'");
You can either enumerate it or call .FirstOrDefault, it's your choice. Each time you call GetSomeData, it will run the query.
Update 3
GetSomeData implemented with earlier versions of C#
public IEnumerable<IDataRecord> GetSomeData(IEnumerable<string> fields, string table, string where = null, int count = 0)
{
var predicate = string.IsNullOrEmpty(where) ? "" : " WHERE " + where;
string sql = string.Format("SELECT {0} FROM {1} {2}", string.Join(",", fields), table, predicate);
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}