Wha datatype is "System:VariableValue" in SSIS? - variables

I need to log every change of variable values in a SSIS, at package level.
I have a SQL Task Editor that receives, as parameters, System::VariableName and System::VariableValue. I use this parameter to log a line in a DB log table.
Everything is working fine BUT... so far i only have numeric variables so, in the "Parameter Mapping", i specificed that the variable with name "System::VariableValue" is a NUMERIC DataType.
What happens when I will have a Datetime variable or a varchar variable? How can I handle variables of different types in this case?
Thankx

Make the datatype sql_variant, which will accommodate the different datatypes.
More on that here: https://msdn.microsoft.com/en-us/library/ms173829.aspx
Also, SSIS does have a on variable changed event which maybe helpful for you, though it sounds like you have a good custom solution.
m
EDIT:
So there is some documentation on MSDN that seems to suggest nvarchar maps to sql_variant. This worked for strings, but left the value empty for numeric values. Looking at the type for Variable.Value in the variables collection in a script task, it notes the type is empty. So I tried setting the data type to null, which did not work at all.
Finally, I created a script task to do the job and this worked correctly. The script task must call a stored proc in order for it to handle all the data types. I tested it with string, int, double and bool, all of which worked correctly.
Here is the table I used:
create table logging (myval sql_variant);
Here is the proc definition:
Create proc [dbo].[insertLog]
#myVal sql_variant
AS
Begin
set nocount on;
insert into logging values(#myVal);
end;
In the OnVariableValueChanged event handler, I added a script task with the following code:
using System.Data.OleDb;
public void Main()
{
// TODO: Add your code here
object val = Dts.Variables["System::VariableValue"].Value;
OleDbConnection conn = new OleDbConnection(Dts.Connections[".\\sql2016.Test"].ConnectionString);
using (conn)
{
conn.Open();
OleDbCommand cmd = new OleDbCommand("insertLog", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#myVal", val);
cmd.ExecuteNonQuery();
}
Dts.TaskResult = (int)ScriptResults.Success;
}
".\sql2016.Test" is the name of the connection manager in the package.
Please see if this will work for you,
m

Related

Sql requires scalar to be declared

The following sql (Sql Server 2016) generates an error:
INSERT INTO Requests (EntryDate,Status, AccountID)
VALUES (#EntryDate,#Status,#accountID)";
try
{
DatabaseConnection.Execute(sql,
new
{
DateTime.Now,
Status = (int)Status.New, '''an enum
accountID,
}, this.Transaction);
This generates the error:
Must declare scalar variable #EntryDate.
If I replace #EntryDate with getdate(), this runs OK. Even though it seems that getdate() is not used. Why this one value?
#EntryDate is a parameter of your command. You must supply it as such, even if the value is unused, otherwise SQL Server will look for a variable named #EntryDate (which likewise doesn't exist).
If you write new { DateTime.Now, ... } you are passing an anonymous object with a property named Now, which can't be mapped to the actual parameter. Change DateTime.Now to EntryDate = DateTime.Now so the name matches up. The question doesn't specify which object-relational mapper you are using (Dapper?) but they will all need to pass named parameters somehow.

Cannot implicitly convert type 'System.Data.DataTable' to 'RxPMIS.DSet01.tbSystemUsersDataTable'

Okay I may be asking this the wrong way, however simply put:
I am using tableAdapters in my dataset (DSet01) and have several Fill / Get data statements that I would like to eliminate by just passing on an SQL statement to populate the main dataset e.g. Main Table Adapter:= "tbSystemUsers" which has a general "Fill" "Get"...i.e. "Select * from tbSystemUsers" ... and instead of adding another query in this tableAdapter I want to create an SQL statement such as "Select * from tbSystemUsers WHERE (userId = #userID)".
And return the dataset which I can view on my data-grid.
I shouldn't have asked this question here: simply put the Project I inherited from a work colleague initially used a auto generated table adapters in its data-set designer. So this time around when i defined my classes, it fails because the GetData containers have already been define.
Either remove the table adapters class Or initialize my output to the same
existing one as in:
psmDS02.tbIssuesDataTable myIssues = new psmDS02.tbIssuesDataTable();
int postID = this.psmDS02.tbIssues[tbIssuesBindingSource.Position].issuesID;
myIssues = (psmDS02.tbIssuesDataTable) PsDataLayer.cls_0_gridsData.Issues_GetData_ID(postID);
The conversion is in the third line. Thanks

SQL Injection protect using MVC - The Stored Procedures included Dynamic SQL

One of my clients using Dynamic SQL as part of the stored procedures. they don't want to change this. I am building MVC Website that should use that risky stored procedures. therefore, using parameters with Entity Framework will not solve the problem.
When i used the old and good SQL helper, i checked all the parameters inside the ExecuteQuery function and tried to find risky keywords. but now, when i'm using the native .NET Entity Framework 5 i have no shared function i can check there for that.
Using validators for every specific field is not good for me. is there an option to make overadding function for the Entity Framework part which execute the SP or Any other ideas how to solve that problem?
You do not say whether the dynamic SQL within the stored procedures uses parameters or not. Assuming not, the best solution would be to encode strings for single quotes at the point of query execution
e.g. create a methodstring EncodeSqlString(string s) { return s.replace("'", "''"); }
Then call this method
cmd.CommandText = "SP_FOO";
cmd.CommandType = CommandType.StoredProcedure;
EntityParameter param = new EntityParameter();
param.Value = EncodeSqlString(myString);
param.ParameterName = "MyParam";
cmd.Parameters.Add(param);
This would be the safest way as you are only encoding the string values as passed to the stored procedure, you are not using the values elsewhere and in contexts where the quote encoding isn't appropriate, and you will be mitigating the risk of truncation (as long as there is no truncation happening within the SPs). This will also only work correctly if the SPs only use the values for constructing SQL queries - if they do anything else with them then this probably isn't the way to go.
Only pass string values into this method. For other, non-quoted types you should ensure that they are the correct type before passing them into the parameter. e.g. for an int
string number = Request.QueryString["Number"];
if (int.TryParse(number, out myInt))
{
cmd.CommandText = "SP_BAR";
cmd.CommandType = CommandType.StoredProcedure;
EntityParameter param = new EntityParameter();
param.Value = myInt;
param.ParameterName = "MyParam";
cmd.Parameters.Add(param);
}
else
{
// handle appropriately but do not use value
}

Call stored function without knowing the parameter names through vb.net

Can some one suggest me how to call a stored function in oracle through vb.net.
From vb.net should i able to pass the values to arguments of that function without knowing the parameter names?
Example: I have a function,
Create or Repalce Function Func_Name(param1 Varchar2,param2 varchar2)
Inorder to call this function through vb.net, we need to give
parameterargs.paramtername="param1"
Is there anyway so that i cannot use the parameter name and call the function
Thanks in advance
Rupesh
The way that we handled it was to open the Oracle DB up through an OleDbConnection, then call GetOleDbSchemaTable asking for the Procedure_Columns.
For example:
DataTable dtTable;
dtData = this.Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Procedure_Columns, new object[] {null, null, sName, null});
foreach (DataRow theRow in dtData.Rows)
{
// Columns available in the row include:
// column_name, data_type, type_name, precision, and scale
}
Then, if you need to execute it without valid parameters (for example, to get the columns it exposes) you could execute it using DbNull.Value for each parameter.
Also, I can't remember exactly how Oracle operates, but in SQL Server you need to include the namespace when executing the function (i.e. select * from dbo.fn_my_test()). Also, depending on how the function is structured, you may have to select from it instead of executing it.
I'm not sure if you can use named parameters with Oracle.
When you create the parameterized query, try using question marks as a place holder:
Select col1, col2 From tablename Where col1 = ? and col2 = ?
Then, be sure to add the parameters to the command object in the correct order.
You don't need to know the parameter names to call it.
You need to know the number and type of them
Adding parameter names to the call means you don't have to pass all of them and / or you can pass them in a different order to the signature of the SP.
Call it like a parameterised query.
PSEUDOCODE
int customer_ID = 786;
Command.CommandText = 'Exec SP_MYProc #MyVar';
Command.Parameters.Add(new Parameter('MyVar',DbType.Int,customer_ID));
Command.Exec

How to retrieve multiple rows from a stored procedure with Linq to SQL?

I've recently started to work with Linq to SQL and wondered how to get multiple rows as a result of executing a stored procedure,here's a simple sp i want to work with:
CREATE PROCEDURE gsp_ftsmultiple
#SearchKey varchar(100)
AS
BEGIN
SET NOCOUNT ON;
SELECT Label, theContent
FROM FtsTest
WHERE FREETEXT( theContent, #SearchKey )
END
Executing this sp from management studio is fine,but the corresponding method in the generated context class returns a int value, and I don't know how to get the actual rows, tried using the OUT parameters, but they can return only one result.
I think all you need to do is make a class that matches your result schema and make sure the function in the dbml has it as a return type.
see here on msdn
Try creating the fulltext predicates as wrapper functions instead of sprocs, like this. Worked for me.
When sqlmetal generates the code for this procedure, it doesn't pass a valid argument for the query to work.
Try to put something like this on the top of you SP:
IF #SearchKey IS NULL OR LEN(#SearchKey) = 0
BEGIN
SELECT N'' AS Label, N'' AS theContent WHERE 1 = 0
END
[...]
It will now deduce that 2 NVARCHAR columns are the usual output and generate code accordingly
PS. Code off my head, untested
Mike
I tested the following code snippet and it worked fine. If you put the generated code here, I can take a look and check where is the problem. Anyway, you can create a partial class as same name as your generated data context class and add the desired method manually as follows.
public partial class FooDataContext: System.Data.Linq.DataContext
{
[System.Data.Linq.Mapping.Function(Name = "GetFoo")]
public System.Data.Linq.ISingleResult<Foo> GetFoo()
{
System.Data.Linq.IExecuteResult res = base.ExecuteMethodCall(this, (System.Reflection.MethodInfo)System.Reflection.MethodInfo.GetCurrentMethod());
return (System.Data.Linq.ISingleResult<Foo>)res.ReturnValue;
}
}
You'd might be better off just running the query in itself, seeing as you're not really doing anything that requires a procedure. Just make sure you escape the search key properly.