System.InvalidOperationException: Cannot perform CAS Asserts in Security Transparent methods - c#

I have a SQL CLR trigger written in C# 4.0 and deployed on SQL Server 2014. Whenever an insertion happens in a table in SQL Server, this CLR trigger's job is to import that row in an Oracle database. So basically I have to import data in Oracle database whenever an insert query is fired on a table in SQL Server 2014. This is my first CLR SQL trigger project and below is what I am doing:
[SecurityCritical]
[OraclePermission(System.Security.Permissions.SecurityAction.Assert, Unrestricted = true)]
[SqlTrigger(Name = "FetchSurvey", Target = "temp", Event = "FOR INSERT")]
public static void FetchSurvey()
{
SqlTriggerContext triggerContext = SqlContext.TriggerContext;
// Create result set to store data
DataSet resultSet = new DataSet();
// Create a new SQL command
using (SqlCommand command = new SqlCommand("SELECT * FROM INSERTED"))
{
// Create a new SQL connection
using (command.Connection = new SqlConnection("context connection=true"))
{
// Connect to the database
command.Connection.Open();
// Execute procedure
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
adapter.Fill(resultSet);
}
// Disconnect from the database
command.Connection.Close();
}
}
SqlPipe sqlP = SqlContext.Pipe;
// Return data
if (resultSet.Tables.Count > 0)
SaveSurvey(resultSet);
sqlP.Send("Finaly its done!!");
}
public static void SaveSurvey(DataSet dsSurvey)
{
using (OracleConnection con = new OracleConnection("my oracle connection string"))
{
if (con.State == ConnectionState.Closed)
con.Open();
DataRowView drv = dsSurvey.Tables[0].DefaultView[0];
using (OracleCommand cmd = new OracleCommand("AddMetaData", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("V_id", drv["TemplateID"]);
cmd.Parameters.AddWithValue("V_Title", drv["TemplateName"]);
cmd.Parameters.AddWithValue("V_CreatedBy", drv["CreatedBy"]);
cmd.Parameters.AddWithValue("V_IsActive", drv["IsActive"]);
cmd.ExecuteNonQuery();
}
}
}
And this is my code to create assembly/deploy trigger:
CREATE ASSEMBLY TriggerImportSurvey
FROM 'C:\ImportSurvey\SQL-CLR-Trigger.dll'
With Permission_Set = External_Access;
Now the problem is whenever I run an insert query in SQL Server to insert data, I got below error in SQL Server:
Msg 6522, Level 16, State 1, Procedure tri_InsertSurvey_clr, Line 18
A .NET Framework error occurred during execution of user-defined routine or aggregate "tri_InsertSurvey_clr":
System.InvalidOperationException: Cannot perform CAS Asserts in Security Transparent methods
System.InvalidOperationException:
at Triggers.FetchSurvey()
tri_InsertSurvey_clr is the trigger which is responsible for executing the assembly whenever I run an insert statement.
Please tell me what I am missing so that I am getting this error, Also if there a more elegant way of implementing a CLR SQL trigger then please also suggest that.
NOTE: When I tried to save the data using a trigger in SQL Server I was successful, but now when I am trying to save it in Oracle database, I am getting this error. Also the Oracle database is installed on another machine.

Related

Can not retrieve a list of tables from an Oracle database - conn.GetSchema("Tables")

I need to retrieve the list the tables in an Oracle database that is defined by a DSN that is using the Oracle ODBC driver.
However, OdbcConnection.GetSchema("Tables") throws an exception ERROR [HYT00] [Oracle][ODBC][Ora]ORA-01013: user requested cancel of current operation\n or ORA-00604: error occurred at recursive SQL level 1 after about 30 seconds.
using (OdbcConnection connection = new OdbcConnection("Driver={Oracle in OraDB18Home1};Dbq=XE;Uid=system;Pwd=mypassword;"))
{
connection.Open();
//Also unsuccessful with "Views" and "Columns", but works with "DataTypes" and "Restrictions"
DataTable schema = connection.GetSchema("Tables");
}
The database is newly installed and is not too big.
I can call GetSchema() without parameters to successfully retrieve all supported schema collections.
I can also successfully run a query against my database:
OdbcCommand command = new OdbcCommand("SELECT * FROM vendors")
{
Connection = connection
};
OdbcDataReader reader = command.ExecuteReader();
You should stop using ODBC. Use ODP.NET - this is gold standard Oracle .NET provider. And use "Managed" version, i.e. Oracle.ManangedDataAccess. This code below will work fine
var conn = new OracleConnection("Data Source=server:1521/sid;password=pwd;user id=usr");
conn.Open();
var tbl = conn.GetSchema();
conn.Close();
Consile.WriteLine(tbl.Rows.Count.ToString());

C# function that calls a SQL stored procedure works when used from local machine but fails when called from an Azure function in the cloud

I created this C# file that takes a JSON document as input, processes data and then sends the processed data to an SQL database. The eventuall plan is to put it in the cloud as an Azure function with a trigger for any new document entering an Azures CosmosDB.
Currently the part of the code responsible for sending the information to SQL looks like this:
public void Store (PushData i)
{
using (SqlConnection conn = new SqlConnection("Server=<serverconnection>;DataBase=<DBName>;User ID=<ID>;Password=<PW>"))
{
conn.Open();
// 1. create a command object identifying the stored procedure
SqlCommand cmd = new SqlCommand("ActualsCreator", conn);
// 2. set the command object so it knows to execute a stored procedure
cmd.CommandType = System.Data.CommandType.StoredProcedure;
// 3. add parameter to command, which will be passed to the stored procedure
cmd.Parameters.AddWithValue("#Date", i.Date);
cmd.Parameters.AddWithValue("#AvailabilityTime", i.MinutesUptime);
cmd.Parameters.AddWithValue("#EnvName", i.EnvName);
cmd.Parameters.AddWithValue("#MeaName", i.MeaName);
cmd.Parameters.AddWithValue("#MeaType", i.MeaType);
cmd.Parameters.AddWithValue("#LastUpdate", i.LastUpd);
cmd.Parameters.AddWithValue("#ClusterStatus", i.Status);
cmd.Parameters.AddWithValue("#ResourceID", i.ResID);
cmd.Parameters.AddWithValue("#MidnightTime", i.MinutesUptimeForMidnight);
// execute the command
using (SqlDataReader rdr = cmd.ExecuteReader())
{
}
}
}
When run localy all the information makes it to the SQL server without an issue, however when run from the azure function it will fail at "#MeaName" or "#EnvName" or "#ResourceID".
[Error] Exception while executing function: Functions.monitorResultFullTrigger. mscorlib: Exception has been thrown by the target of an invocation. .Net SqlClient Data Provider: Procedure or function 'ActualsCreator' expects parameter '#MeaName', which was not supplied.
Whichever one fails is whichever one is stated first in the code. The only thing these 3 have in common over all the other types is they are stored as nvarchar(50) in the SQL database. The error message indicates that nothing is being passed to the parameter, but the exact same code doesnt have this issue localy, and none of the other variables but those 3 have this issue either.
My question is what can cause this? Why does it only fail in the Azure function when in the cloud and why only the nvarchar types.
Please try to specify the SqlDbType in our code, we can do like below:
SqlParameter para = new SqlParameter("#MeaName", SqlDbType.NVarChar) { Value = i.MeaName };
cmd.Parameters.Add(para);
Hope it will be helpful
Try like the below one for all the parameters
using (SqlConnection sqlConnection = new SqlConnection(CONNECTIONSTRING))
{
using (SqlCommand sqlCommand = new SqlCommand(#"ActualsCreator", sqlConnection))
{
//define sqlcommandtype as SP
sqlCommand.CommandType = CommandType.StoredProcedure;
//define induvidual parameters for the SP
SqlParameter Param_MeaName = sqlCommand.CreateParameter();
Param_MeaName.ParameterName = #"#MeaName";
Param_MeaName.SqlDbType = SqlDbType.NVarChar;
Param_MeaName.Size = 50;
Param_MeaName.Direction = ParameterDirection.Input;
Param_MeaName.Value = i.MeaName;
//Add the paramters in the sqlcommand
sqlCommand.Parameters.Add(Param_Order_Key);
//Open the connection
sqlConnection.Open();
//Execute the SP
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();

Sqlite for .net can't add column using alter table

SQL script is:
ALTER TABLE SYNC_INFO
ADD COLUMN DB_VERSION INTEGER;
UPDATE SYNC_INFO
SET DB_VERSION = 1
WHERE ID = 0;
C# code is:
using (DbConnection con = new SQLiteConnection("Data Source=" + Filename + ";Version=3"))
{
con.Open();
using (DbCommand command = con.CreateCommand())
{
command.CommandText = script;
command.ExecuteNonQuery();
}
}
The problem is sqlite says "database is locked" while trying to evaluate the ALTER TABLE command. All over operations like read/write rows are successful.
Another one - Mozilla's SQLite manager successfully evaluating this script.
Is it possible problem in .net wrapper of SQLite?
You can get the error message "database is locked" only when some other connection has an active transaction.
That transaction might be from some forgotten connection in your program, or in some other program accessing the database.

Connecting to mysql on 000webhost using C#

Im simply just trying to read what there is in the batabase on to a console but i always get an exception on the conn.Open() line. Here is all the code:
SqlConnectionStringBuilder conn_string = new SqlConnectionStringBuilder();
conn_string.DataSource = "mysql14.000webhost.com"; // Server
conn_string.UserID = "a7709578_codecal";
conn_string.Password = "xxxxx";
conn_string.InitialCatalog = "a7709578_codecal"; // Database name
SqlConnection conn = new SqlConnection(conn_string.ToString());
conn.Open();
SqlCommand cmd = new SqlCommand("Select name FROM Users");
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("{1}, {0}", reader.GetString(0), reader.GetString(1));
}
reader.Close();
conn.Close();
if (Debugger.IsAttached)
{
Console.ReadLine();
}
You need to build the connection string manually or use MySqlConnectionStringBuilder. MySql uses a different format than SQL Server and the SqlConnectionStringBuilder that you're using. You also need to use a MySQL library, SqlConnection, SqlCommand, etc are all build specifically for SQL Server.
MySQL connectors
For MySQL database you are using wrong provider. Those classes you have used in posted code are for SQL Server. Your code should look like below with MySQL provider related classes
MySqlConnectionStringBuilder conn_string = new MySqlConnectionStringBuilder();
conn_string.Server = "mysql14.000webhost.com";
conn_string.UserID = "a7709578_codecal";
conn_string.Password = "xxxxxxx";
conn_string.Database = "a7709578_codecal";
using (MySqlConnection conn = new MySqlConnection(conn_string.ToString()))
Check Related post in SO
Also to point out, you are selecting only one column from your table as can be seen
new SqlCommand("Select name FROM Users");
Whereas trying to retrieve two column value, which is not correct
Console.WriteLine("{1}, {0}", reader.GetString(0), reader.GetString(1))
000webhost free servers does not allow external connections to the server database.
You can only use your database from your PHP scripts stored on the server.
You can get data from database using PHP and it will return.So i advice to you using php from C# like api.

How I can Select a Table from a SQL Server Database correctly?

I want to built a connection to a SQL Server database with a SELECT command.
The connection is ok but I get a error if I make a error. I want to get the Select values to a DataTable.
This I get if I try this:
The SELECT-Perssision was denied for UserApplicationRequests-Objekt, DB_CM0-Datenbank, dbo-Schema.
I use a Login Dialog in my application for building the connection string. In this form:
user id=[username];password=[password];server=[servername];Trusted_Connection=yes;database=DB_CM0
And here is my code for the SELECT command.
public DataTable GetDataTable(string sql)
{
using (con = new SqlConnection(connectionstring))
{
try
{
SqlCommand command = new SqlCommand(sql, con);
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable tb = new DataTable();
adapter.Fill(tb);
con.Open();
command.ExecuteReader();
return tb;
}
catch (Exception)
{
return null;
}
}
}
My SQL command:
string sql = "SELECT * FROM [DB_CM0].[dbo].[UserApplicationRequests]";
its happening because of security issue..below steps might help you
Open SQL Server Management studio
Navigate to the database 'CNET_85731' >> Security >> Users
Right click on the one which you are using in your code
And finally, just uncheck 'db_denydatareader' inside "Database Role
membership" section.
Your connection string uses the sql authentication login method and integrated security login method simultaneously... Windows integrated security will have the priority in this case and attempt to use your windows user permissions to interact with the database... maybe this is not the behaviour you intended.

Categories