I just want to se if my stored procedure selects any rows.
using (var conn = new System.Data.SqlClient.SqlConnection(
"Data Source=DANIEL-DATOR;Initial Catalog=EvaluationTest;Integrated Security=True"))
using (var command = new SqlCommand("countRecords", conn))
{
conn.Open();
command.Parameters.Add(new SqlParameter("#usermail", prop.Sendmail));
command.CommandType = CommandType.StoredProcedure;
int userCount = (int)command.ExecuteScalar();
conn.Close();
if (userCount > 0)
{
return 1;
}
return 2;
i get this error from the code: System.InvalidCastException: Specified cast is not valid.
What am i doing wrong?
ExecuteScalar will return null if the set of results is empty; bear in mind that the way this function works is that it takes the value of the first column of the first row of the returned data.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx
It must be the case that your Stored Procedure is not returning anything at all; so you should check if the result is null:
var result = command.ExecuteScalar();
if (result!=null)
{
//you got some data
Int32.TryParse(result.ToString, out userCount);
return user Count>0?1:2;
}
Related
How do I run a raw query in ASP.NET core to return the row count from a table?
Currently, I am doing this and the returned result is -1. I think the return result is based on the number of records affected.
int numberOfRows = await
appDbContext.Database.ExecuteSqlInterpolatedAsync(
$"SELECT CODE FROM [samaster] WHERE CODE={productBrandCode} AND WAREHOUSE={warehouse} ");
Any idea on how to get the count back to numberOfRows variable will be appreciated.
NOTE: The above table is not a model so I need to run a raw query.
Thanks
It is currently not possible to get the query result when using ExecuteSqlInterpolatedAsync. The same applies to any additional LINQ Statements.
You can, however, use the underlying ADO.net Provider:
public IList<IDictionary<string, dynamic>> SelectDynamic(string table)
{
using (var command = Database.GetDbConnection().CreateCommand())
{
command.CommandText = $"SELECT * FROM [{table}]";
command.CommandType = CommandType.Text;
Database.OpenConnection();
using (var result = command.ExecuteReader())
{
var entities = new List<IDictionary<string, dynamic>>();
while (result.Read())
{
var dict = new Dictionary<string, dynamic>();
for (int i = 0; i < result.FieldCount; i++)
{
dict.Add(result.GetName(i), result.GetValue(i));
}
entities.Add(dict);
}
return entities;
}
}
}
Add this to your DbContext Class and Call it with:
using (var context = new MyDbContext()) // Or get it with DI, depends on your application
{
var count = context.SelectDynamic("samaster").Where(d => d["CODE"] == productBrandCode && d["WAREHOUSE"] == warehouse).Count();
}
Beware, however, that this is an expensive operation if you have a lot of rows in your table!
An alternative approach to only fetch the relevant results would be to replace
command.CommandText = $"SELECT * FROM [{table}]";
with
command.CommandText = $"SELECT CODE FROM [samaster] WHERE CODE={productBrandCode} AND WAREHOUSE={warehouse}";
and pass the parameters as function parameters.
public IList<IDictionary<string, dynamic>> SelectDynamic(string productBrandCode, string warehouse)
{...
Also make sure to escape all parameters if they are in any way submitted by user input to prevent SQL Injection Attacks!
There are two common approaches :
A.
int numberOfRows = await appDbContext.Database.ExecuteSqlInterpolatedAsync($"SELECT CODE FROM [samaster] WHERE CODE={productBrandCode} AND WAREHOUSE={warehouse} ").Count();
B.
int numberOfRows = await appDbContext.Database.ExecuteSqlInterpolatedAsync($"SELECT count(*) FROM [samaster] WHERE CODE={productBrandCode} AND WAREHOUSE={warehouse} ").First();
Since nobody gave me the correct answer. I end up using the following.
public async Task<bool> IsAValidProduct(string productBrandCode)
{
int count = 0;
await using DbCommand command = appDbContext.Database.GetDbConnection().CreateCommand();
command.CommandText =
"SELECT COUNT(CODE) FROM [samaster] WHERE CODE=#productBrandCode AND WAREHOUSE=#warehouse ";
command.CommandType = CommandType.Text;
command.Parameters.Add(new SqlParameter("#productBrandCode", SqlDbType.VarChar)
{Value = productBrandCode});
command.Parameters.Add(new SqlParameter("#warehouse", SqlDbType.VarChar)
{Value = warehouse});
await appDbContext.Database.OpenConnectionAsync();
count = (int) await command.ExecuteScalarAsync();
await appDbContext.Database.CloseConnectionAsync();
return count == 1;
}
int c= dbObj.Database.ExecuteSqlRaw(sql); //User this code
I am making a straightforward application using AngularJS and ASP.NET, which I am fairly new to. I created an SQL procedure but every time I have it executed, it throws the following error:
System.Data.SqlClient.SqlException: 'Procedure or function 'LoginProc'
expects parameter '#IsValid', which was not supplied.'
How do I resolve this exception? Here is the code for storing the procedure:
ALTER PROCEDURE LoginProc
#username VARCHAR(50),
#password VARCHAR(MAX),
#IsValid bit out
AS
BEGIN
SET #IsValid=(SELECT COUNT(username) from "User" WHERE username=N'#username' and password=N'#password')
END
And here is the code that attempts to execute the procedure:
public class db
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings
["dbconnect"].ConnectionString);
public int userlogin(User user)
{
int res;
SqlCommand cmd = new SqlCommand("LoginProc", con);
cmd.CommandType = CommandType.StoredProcedure;
if (user.username != null && user.password != null) {
cmd.Parameters.AddWithValue("#username", user.username);
cmd.Parameters.AddWithValue("#password", user.password);
SqlParameter oblogin = new SqlParameter();
oblogin.ParameterName = "#IsVaild";
oblogin.Direction = ParameterDirection.Output;
oblogin.SqlDbType = SqlDbType.Bit;
cmd.Parameters.Add(oblogin);
con.Open();
cmd.ExecuteNonQuery();
res = Convert.ToInt32(oblogin.Value);
con.Close();
}
else
{
res = 0;
}
return res;
}
}
You have just mispelled #IsValid here:
oblogin.ParameterName = "#IsVaild";
I have what seems like a common problem but without any obvious errors.
I've already seen all related threads and I can see no similarity to my problem because I am not making any "obvious" mistake, at least not similar to the others.
My stored proc declaration:
CREATE PROCEDURE [dbo].[sp_AddEventTemp]
#iUserID int,
#iVerb int,
#iObject int,
#iResult int,
#nTransactionID numeric Output
And the code:
var userId = 9530;
var verb = 2;
var objectId = 15;
var transactionId = 0;
using (var connection = new SqlConnection(ConnectionString()))
{
var command = new SqlCommand('sp_AddEventTemp', connection)
{
CommandType = CommandType.StoredProcedure
};
command.Parameters.Add(new SqlParameter("#iUserID", userId)
{
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int
});
command.Parameters.Add(new SqlParameter("#iVerb", verb)
{
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int
});
command.Parameters.Add(new SqlParameter("#iObject", objectId)
{
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int
});
command.Parameters.Add(new SqlParameter("#iResult", 0)
{
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int
});
command.Parameters.Add(new SqlParameter("#nTransactionID", 0)
{
Direction = ParameterDirection.Output,
SqlDbType = SqlDbType.Int
});
// execute
connection.Open();
transactionId = (int)command.ExecuteScalar();
connection.Close();
}
return transactionId;
And I get:
Procedure or function 'sp_AddEventTemp' expects parameter '#iResult' which was not supplied
Even though it clearly IS supplied!
I did this test by running this on SQL server directly:
sp_AddEventTemp 9530, 2, 15, 0, 0
And it worked perfectly. I got: (1 row(s) affected)
So there is nothing wrong with the stored procedure itself. There must be something in the code and I can't figure it out because it looks correct to me.
I do the same for other similar stored procedures and they all work fine.
Any ideas?
Thanks in advance
Could it be some sort of follow-up-error due to the mismatch between the procedure's datatype for #nTransactionID and your usage of it in the code (numeric/int)?
I am trying to update a few columns in a Oracle table from my C# code.
Here is my method:
private static bool UpdateOracleTable(OracleTable table, string whereClause, List<int> entIDs)
{
try
{
var tableName = table.ToString();
using (OracleConnection conn = new OracleConnection(_oracleConnection))
{
conn.Open();
foreach (var id in entIDs)
{
whereClause = String.Format(whereClause, id);
var query = Resources.UpdateOracle;
query = String.Format(query, tableName, "20", DateTime.Now.ToString("yyyy/MM/dd"), whereClause);
using (OracleCommand cmd = new OracleCommand(query, conn))
{
cmd.ExecuteNonQuery();
}
}
}
return true;
}
catch (Exception ex)
{
Log.Debug(LogType.Error, ex);
return false;
}
}
Here is the Query:
UPDATE
{0}
SET
SYNC_STATUS = '{1}'
,SYNC_DATE = TO_DATE('{2}', 'yyyy/mm/dd')
{3}
And the where clause will look something like:
WHERE ID = {0}
This method updates about 10 records, and the rest stays null. This mehod does return true, and I have debugged, no exception is thrown.
Why does it not update all records?
This isn't an answer but might help debug the problem.
Instead of the like:
cmd.ExecuteNonQuery();
put in this:
int count = cmd.ExecuteNonQuery();
if (count == 0)
{
Console.WriteLine("");
}
Put a break on the Console.WriteLine("") and run it. The debugger will stop if no rows were updated. You can then check the query, and whether or not that ID actually exists.
The problem was with the WHERE clause. Since it contains a place holder {0}, after I I formatted the WHERE clause, the ID always stayed to the value it was formatted with first.
This is what my new method looks like.
private static bool UpdateOracleTable(OracleTable table, string whereClause, List<int> entIDs)
{
try
{
var tableName = table.ToString();
using (OracleConnection conn = new OracleConnection(_oracleConnection))
{
conn.Open();
foreach (var id in entIDs)
{
string originalWhere = whereClause;
originalWhere = String.Format(originalWhere, id);
var query = Resources.UpdateOracle;
query = String.Format(query, tableName, "20", DateTime.Now.ToString("yyyy/MM/dd"), originalWhere);
using (OracleCommand cmd = new OracleCommand(query, conn))
{
bool success = cmd.ExecuteNonQuery() > 0;
}
}
}
return true;
}
catch (Exception ex)
{
Log.Debug(LogType.Error, ex);
return false;
}
}
As can be seen, I added a variable 'originalWhere', that gets formatted, but most importantly, is being set to original WHERE clause parameter passed, so that it will always contain the place holder.
I can't get what is happening to my app. I'm using a SQL CE (.sdf file) to a local database (winform app) and when I debug, everything runs pretty well, I have in the end of it the message that my data was inserted well. But later on, when I check my databse, its empty.
What should I do?
This is my code:
SqlCeConnection conn = new SqlCeConnection(#"Data Source=|DataDirectory|\Database\Livraria.sdf;");
SqlCeCommand cmd = new SqlCeCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"INSERT INTO Livros (Codigo, ISBN, Titulo, Editora, Localizacao, Valor, QTD, Autor, AutorEspiritual, Data_)
VALUES (#Codigo, #ISBN, #Titulo, #Editora, #Localizacao, #Valor, #QTD, #Autor, #AutorEspiritual, #Data_)";
cmd.Parameters.AddWithValue("#Codigo", codigo);
cmd.Parameters.AddWithValue("#ISBN", isbn);
cmd.Parameters.AddWithValue("#Titulo", titulo);
cmd.Parameters.AddWithValue("#Editora", editora);
cmd.Parameters.AddWithValue("#Localizacao", localizacao);
cmd.Parameters.AddWithValue("#Valor", valor);
cmd.Parameters.AddWithValue("#QTD", entradas);
cmd.Parameters.AddWithValue("#Autor", autor);
cmd.Parameters.AddWithValue("#AutorEspiritual", autorEspiritual);
cmd.Parameters.AddWithValue("#Data_", data_);
try
{
conn.Open();
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Livro adicionado com sucesso!");
}
else
{
MessageBox.Show("O livro não foi adicionado.");
}
// Reset campos
Codigo.Text = "";
Titulo.Text = "";
Editora.SelectedIndex = 0;
Valor.SelectedIndex = 0;
Localizacao.SelectedIndex = 0;
Entrada.Text = "";
Isbn.Text = "";
Autor.SelectedIndex = 0;
AutorEspiritual.SelectedIndex = 0;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
conn.Close();
}
You have two databases. You are inserting to one and looking for the results in another.
Or, you are starting a transaction, inserting but then not committing.
The first thing you need to do is to create a simple select statement first that gets record from you sqlce database.
if( has record//connected )
{
//Proceed to your insert statement remove if else and use
conn.Open();
cmd.ExecuteNonQuery()
//then check your DB again
}
else
{
//Problem on you connection string
}
Your sqlce database is located on your bin folder
Regards