Error trying to execute sql from inside SQL CLR - sqlclr

I have the following code:
[SqlFunction(DataAccess = DataAccessKind.Read, SystemDataAccess = SystemDataAccessKind.Read)]
public static int GetInt()
{
int retValue = 0;
using (SqlConnection conn = new SqlConnection("context connection = true"))
{
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select MyInt from SomeTable";
object timeOut = cmd.ExecuteReader(); // <- error happen here
}
return retValue;
}
I get the following exception in
cmd.ExecuteReader();
{"This statement has attempted to access data whose access is restricted by the assembly."}

As a side note, if you're trying to access temporary tables created with #, such as #tmp, you need to also put in SystemDataAccess = SystemDataAccess.Read. Another way around this would be to use a common table expression to get your data.

I needed to add DataAccess = DataAccess.Read to the function attribute in order to do that.

Related

Assign query result to a variable and return variable

private int getuserid(String username){
SqlConnection con = new SqlConnection(_conString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT USER_ID from tblUser where USERNAME ='" +username+"'";
int locid = Convert.ToInt32(cmd.CommandText);
return locid;
}
Hi everyone, do you have an idea on how to assign value of user_id in a variable and return it. I tried but I am not sure its good.
You need to actually open the connection and run the command.
You should also take measures to protect against sql injection and leaving the connection open in the event of an exception. This code solves all three concerns:
private int getuserid(String username)
{
using (var con = new SqlConnection(_conString))
using (var cmd = new SqlCommand("SELECT user_id FROM tblUser WHERE username = #username", con))
{
// Use actual column type and length from the database
cmd.Parameters.Add("#username", SqlDbType.NVarChar, 30).Value = username;
con.Open();
return (int)cmd.ExecuteScalar();
}
}
Finally, you need to define what you want to happen if there's no match for your WHERE clause. Right now there will be an exception, but that's also true for the original code in the question, so as far as I know at this time that's what you actually want to do.
try
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT USER_ID from tblUser where USERNAME =#username";
cmd.Parameters.Add("#username", SqlDbType.NVarChar, 30).Value = username;
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
int locaid = Convert.ToInt32(reader.GetOrdinal("USER_ID"));
}
}
}
OR
int locaid = (int) cmd.ExecuteScalar();

MySql Stored Procedure doesn't return data when call from Asp.net Core Application

I've created a Stored Procedure in MySQL. When I call that procedure with a parameter in MySQL Workbench, it gives some data when I call it with same parameter from my Asp.net Core Code, It doesn't return any row. Here is my code, Is there any problem in the code?
DBConnection context = HttpContext.RequestServices.GetService(typeof(DBConnection)) as DBConnection;
using (var con = context.getConnection())
{
string command = "PS19_CLIENTDATA_SELECT";
con.Open();
MySqlCommand cmd = new MySqlCommand(command,con);
string id = User.FindFirstValue(ClaimTypes.NameIdentifier);
cmd.Parameters.AddWithValue("#user_ID", id);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
var reader = cmd.ExecuteReader();
while(reader.Read())
{
ClientDataViewModel tempModel = new ClientDataViewModel();
tempModel.Filename = reader["FileName"].ToString();
tempModel.userID = reader["userID"].ToString();
tempModel.isDirectory = (bool)reader["isDirectory"];
tempModel.remarks = reader["Remarks"].ToString();
tempModel.userName = reader["UserName"].ToString();
model.Add(tempModel);
}
con.Close();
}
I think you have to use call to execute stored procedure.
e.g., string command = "call PS19_CLIENTDATA_SELECT('input1','input2',...)"

How to pass the output parameter for MySQL stored procedure for .net core using Pomelo ORM

Here is my SP in MySQL
CREATE PROCEDURE `GetMemberID`(
IN uname VARCHAR(128),
OUT MemberID INT
)
BEGIN
SELECT ID INTO MemberID FROM `Member` Where username = uname;
END
And I am calling SP from .netcore web api project that is using Pomelo ORM.
var usernameParam = new MySqlParameter
{
ParameterName = $"#uname",
DbType = DbType.String,
Direction = ParameterDirection.Input,
Value = "test"
};
var memberIDParam = new MySqlParameter
{
ParameterName = $"#MemberID",
DbType = DbType.Int32,
Direction = ParameterDirection.Output
};
rContext.Database.ExecuteSqlRaw($"Call GetMemberID (#uname=#uname, #MemberID=#MemberID OUT)"
, usernameParam , memberIDParam);
I am getting the following error when used output parameter.
Only ParameterDirection.Input is supported when CommandType is Text (parameter name: #MemberID)
How can I pass output parameter?
It's a known issue in github ,as mguinness commented
RelationalCommand.csdon't specify CommandType so it'll default to CommandType.Text which means output parameters won't work.
Here is a workaround ,you could refer to
using (MySqlConnection lconn = new MySqlConnection(Configuration.GetConnectionString("DefaultConnection")))
{
lconn.Open();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = lconn;
cmd.CommandText = "GetMemberID"; // The name of the Stored Proc
cmd.CommandType = CommandType.StoredProcedure; // It is a Stored Proc
cmd.Parameters.AddWithValue("#uname", "sherry");
cmd.Parameters.Add("#MemberID", MySqlDbType.Int32);
cmd.Parameters["#MemberID"].Direction = ParameterDirection.Output; // from System.Data
cmd.ExecuteNonQuery();
Object obj = cmd.Parameters["#MemberID"].Value;
var lParam = (Int32)obj; // more useful datatype
}
}
Reference :How to call stored procedure in Entity Framework Core with input and output parameters using mysql

SqlDependency failed because A SELECT statement that cannot be notified or was provided

I'm trying to use SqlDependency, And I read articles Creating a Query for Notification, Query Notification Permissions from Microsoft. I double checked many times, it seems all meet what it needs which mentions in articles Here is my code.
private void InitialSqlDependency()
{
using (var connection = new SqlConnection(_connString))
{
connection.Open();
string message = string.Empty;
string query = #"SELECT ModifiedOn FROM [dbo].[ContainerTransactions]";
using (var command = new SqlCommand(query, connection))
{
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(Dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
SqlDataReader dr = command.ExecuteReader();
if (dr.HasRows)
{
dr.Read();
message = dr[0].ToString();
}
}
}
}
private void Dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
_logger.Debug("ContainerWatch Dependency Fired!");
if (e.Type == SqlNotificationType.Change)
{
_logger.Debug("ContainerWatch Change Fired!");
this.InitialSqlDependency();
}
}
However, It always failed to subscribe. And I see SqlNotificationInfo returns Query which means A SELECT statement that cannot be notified or was provided. Here is my debug img
The SELECT statement is extremely simple, Is there any possible reason causing fail?
I found the root cause, because The statement must not reference tables with computed columns. I use a query below to see computed columns
SELECT * FROM sys.computed_columns WHERE object_id = OBJECT_ID('ContainerTransactions')
Therefore, I think I can't use SqlDependency on this table.

Access import into SQL server not importing first line

I am using a function to import data from a access db into SQL server:
public string importDataFromAccess(string table, string fileName)
{
OleDbConnection OleDbConn = new OleDbConnection(String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", fileName));
try
{
string sSQLTable = table;
string myExcelDataQuery = "Select * from " + sSQLTable;
string sSqlConnectionString = connStr;
string sClearSQL = "DELETE FROM " + sSQLTable;
SqlConnection SqlConn = new SqlConnection(sSqlConnectionString);
SqlCommand SqlCmd = new SqlCommand(sClearSQL, SqlConn);
SqlConn.Open();
SqlCmd.ExecuteNonQuery();
SqlConn.Close();
OleDbCommand OleDbCmd = new OleDbCommand(myExcelDataQuery, OleDbConn);
OleDbConn.Open();
OleDbDataReader dr = OleDbCmd.ExecuteReader();
SqlBulkCopy bulkCopy = new SqlBulkCopy(sSqlConnectionString);
bulkCopy.DestinationTableName = sSQLTable;
while (dr.Read())
{
bulkCopy.WriteToServer(dr);
}
OleDbConn.Close();
return "Done";
}
catch (Exception ex)
{
OleDbConn.Close();
return ex.ToString();
}
}
I noticed it isnt importing the first record of each table, can anyone help notice why and how to fix? Hopefully it is only the first row...
You shouldn't need the
while (dr.Read())
{
bulkCopy.WriteToServer(dr);
}
And you just need to replace that with
bulkCopy.WriteToServer(dr);
The WriteToServer method
Copies all rows in the supplied IDataReader to a destination table
specified by the DestinationTableName property of the SqlBulkCopy
object.
But the dr.Read() that you have called has read the first line out of the Reader and advanced the IDataReader to the next record (so it is not accessible to the WriteServer method).