SSIS Execute SQL Task contain Insert Into and Select - sql

I am attempting to read file names then input each name in a row with another similar cell value to another table column. Within the For Each Loop, then I have the Execute SQL Task. currently the Task is set to Direct Input. This is the problem script
INSERT INTO TableB
(LoopValue, Columnvalue)
VALUES (?, N'Select Columnvalue from TableA where Columnvalue like ?')

You have a for each loop over files, as I understood it? When I have these kind of situations I simply map the current file to a fileName variable using the "Variable Mapping" setting of the foreach loop, using index 0.
Then I create a Data Flow task with a derived column which is simply your fileName variable. Using this in conjunction with an OLE DB destination ought to be sufficient to insert the value into a table, if I understand you correct?
EDIT:
Oh you want to create a string as well? You could achieve that in your Control Flow using an Expression Task. Assign a string variable, such as "queryString" and then have:
#queryString = "Select " + #[User::fileName] + " from Table B"
or something in the lines of that, i.e. use "" to insert "hard coded" values and a + followed by your variable to concatenate your variable. You could then also use a derived column for your #queryString variable in your data flow as well.

You're close if I understand what you are attempting to do which is insert into TableB selecting records from TableA where ColumnValue is like the passed in value.
The way you have it now it wants to insert the literal string of Select Columnvalue from TableA where Columnvalue like ? into your table.
Tweak your statement like this:
INSERT INTO TableB (LoopValue, Columnvalue)
SELECT ?, Columnvalue FROM TableA WHERE Columnvalue LIKE '%' + ? + '%' --% is a wildcard. If you only want those that begin or end then remove one or the other %
Then make sure you're passing in the value twice. Since there are multiple ? that relates to the number of parameters, but you can pass it twice since you are using the same value in two different places:
Parameter names would then start with 0 and increment up to match the ? in your statement. Depending on your connection type that could be different, there is a section in the following documentation that tells you what it should be Execute SQL Task

Related

Comparing 2 strings and find out mismatches

I need to create a query in MariaDB 10.2. I am trying to create a query with string functions as now
Below is the scenario
One string has placeholders and another string has values of those placeholders. I want to get a tabular output in which one column have placeholders and another column have placeholder's values
value1 -->
jdbc:postgresql://$PGHOST_1$:$PGPORT_INSTANCE_1$/eventstore
value2 -->
jdbc:postgresql://1.2.3.4:5432/eventstore
now i want to get below data
Thanks in advance.
This needs a looping mechanism. Therefore, use a stored procedure or client code to do the looping:
SELECT placeholder, `value` FROM mylist;
`col` starts out looking like `value1`
foreach row in the list of replacements:
UPDATE mytable SET col =
REPLACE(col, placeholder, `value`);
Now `col` looks like your `value2`
or, if you don't want to change col:
SELECT placeholder, `value` FROM mylist;
SELECT #col := col FROM mytable;
foreach row in the list of replacements:
SET #col =
REPLACE(#col, placeholder, `value`);
then use #col in subsequent work
(value is a keyword, hence the backtics.)
From there, build the "mismatches".

FnSplit not working for SQL stored procedure to take multiple parameters

I have a stored procedure that currently takes in one value(ChainId) for a parameter. I am trying to allow the user to select multiple values of(ChainId). My where statement is below. Could someone help point me in a better direction than I am going now. Currently the query will run and return no data if I select multiple values for the parameter.
WHERE EndAuth is null AND CL.CHIND in(
SELECT [Value] FROM dbo.FnSplit(#ChainId, ','))
ORDER BY CL.CHIND
This is a popular function in SQL Server, so I'll assume you're working with that. Make sure your parameter is of type Varchar(MAX). #ChainId is passed as your string (ideally for SSRS) and ',' is passed as your delimiter. In SSRS, if you have a text box for your users to manually enter multiple values, they will enter something like 'value1, value2, value3'.
Test this out:
Declare #Yes_No Varchar(Max)
Set #Yes_No = 'y,n'
Select #yes_no
Select * from SplitString('y,n',',')
Select * from SplitString(#Yes_No,',')
Your results will be
y,n
----
y
n
----
y
n
Why I say to use Varchar(Max) and not int, or Varchar(10) for example, is because that would stop the function from reading all the values prematurely.
Try this:
Declare #Yes_No Varchar(1)
Set #Yes_No = 'y,n'
Select * from SplitString(#Yes_No,',')
The result will be:
y
The reason is because the function only accepts a value of 1 character in length, and splits that. As you can see, there isn't much to split.
This is just the way SSRS accepts parameters. FN_Split isn't necessarily a built-in function, but a widely popular one designed to allow you to pass multiple values to a string, with a pre-specified delimiter. So make sure you also go to your parameter in the report and specify that it will allow for multiple values. You will also want to supply a list of potential values for your users to select from. You'll either do this by manually populating a small list or providing another data source in the form of a stored procedure or table.

How do you pass values for a parameter by position when you need to check multiple values?

I created a stored procedure (spBalanceRange) with 2 optional parameters. They've been set to a default value and the sp works fine when I pass only 1 value per parameter by position. However, I have a situation where I'm trying to pass, by position, two strings immediately followed by a wildcard. I want the user to be able to search for Vendor names that start with either 'C%' or 'F%'. Here's the gist of the CREATE PROC statement:
CREATE PROC spBalanceRange
#VendorVar varchar(40) = '%',
#BalanceMin money = 1.0
...
Here's what I've tried so far, but doesn't work:
EXEC spBalanceRange '(C%|F%)', 200.00;
EXEC spBalanceRange 'C%|F%', 200.00;
Is there a way to check for 2 or more string values with a wildcard when passed by position? Thanks.
EDIT: According to your comments you are looking for the first letter of a vendor's name only.
In this special case I could suggest an easy, not well performing but really simple approach. CHARINDEX returns a number greater than zero, if a character appears within a string. So you just have to pass in all your lookup-first-characters as a simple "chain":
DECLARE #DummyVendors TABLE(VendorName VARCHAR(100));
INSERT INTO #DummyVendors VALUES
('Camel Industries')
,('Fritz and Fox')
,('some other');
DECLARE #ListOfFirstLetters VARCHAR(100)='CF';
SELECT VendorName
FROM #DummyVendors AS dv
WHERE CHARINDEX(LEFT(dv.VendorName,1),#ListOfFirstLetters)>0
This was the former answer
Checking against more than one value needs either a dedicated list of compares
WHERE val=#prm1 OR val=#prm2 OR ... (you know the count before)
...or you use the IN-clause
WHERE LEFT(VenoderName,1) IN ('C','F', ...)
...but you cannot pass the IN-list with a parameter like ... IN(#allValues)
You might think about a created TYPE to pass in all your values like a table and use an INNER JOIN as filter: https://stackoverflow.com/a/337864/5089204 (and a lot of other examples there...)
Or you might think of dynamic SQL: https://stackoverflow.com/a/5192765/5089204
And last but not least you might think of one of the many split string approaches. This is one of my own answers, section "dynamic IN-statement": https://stackoverflow.com/a/33658220/5089204
I'm answering my own question, and maybe other solutions exist but here is what had to happen with my stored procedure in order to pass variables by position:
CREATE PROC spBalanceRange
#VendorVar varchar(40) = '%',
#BalanceMin money = 1.0
AS
IF (#VendorVar = '%' AND #BalanceMin IS NULL OR #BalanceMin = '')
BEGIN
PRINT 'BalanceMin cannot be null.';
END
IF (#VendorVar = % AND #BalanceMin IS NOT NULL)
BEGIN
(sql statement using parameters)
END
EXEC spBalanceRange '[C,F]%', 200.00;
That's what I know.

Create INSERT statement using parameter

I need to create a INSERT statement using parameters. Say I have two variable name #DestinationFields, #InsertValues.
Here #DestinationFields contain the column name like: product,price and #InsertValues contains the values for those two columns, like: Book,100.
Now, How i create a insert command to insert those values where each value need to add a quotation mark .I already tried as
I already tried as
EXEC('INSERT into tbl_test('+#DestinationFields+')values('+#InsertValues+')')
But it's returning an error.
The name "book" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some
contexts) variables. Column names are not permitted.
How do I do it? Thanks in advance.
Pretending there is no problem of SQL injection here*, you can quickly fix your code by adding quotation marks around Book. The value of # InsertValues should be
'Book', 100
instead of simply
Book, 100
You need to add quotation marks around each string value; otherwise, strings are interpreted as names, which is not valid.
EDIT : (in response to a comment) If all columns are of varchar type, you can put quotes around the entire string, and replace all commas with the quote-comma-quote pattern, like this:
values('''+REPLACE(#InsertValues,',',''',''')+''')'
* You should not put code like this into production, because it can be manipulated to harm your system rather severely. Here is a good illustration of the problem (link).
Try:
DECLARE #DestinationFields VARCHAR(200);
SET #DestinationFields = 'Col1, Col2, Col3'
DECLARE #InsertValues VARCHAR(200);
SET #InsertValues = '1, 2, 3'
DECLARE #SQLString VARCHAR(1000);
SET #SQLString = 'INSERT INTO tbl_test (' + #DestinationFields + ') VALUES (' + #InsertValues + ')';
EXEC (#SQLString)
However, this is very open to SQL Injection attacks. But, it will do what you require.
The Curse and Blessing of Dynamic SQL

SQL query like filter

I need to execute a search query in SQL Server where I need to filter out data based upon an user input textfield.
The problem is, this query needs to be executed on several tables (so I only know the tablecolumns at runtime).
This is the query I have:
SELECT * FROM [BTcegeka.C2M].[dbo].[Lookup_Country] WHERE Name LIke '%test%'
Now the problem is I need to do the Like function on every column (I only know the columnname at runtime) in the table. I am calling this query from an ASP.NET website. The user selects a table from a dropdownlist and can then enter the search field.
This is what I really want to accomplish:
SELECT * FROM [BTcegeka.C2M].[dbo].[Lookup_Country] WHERE * LIke '%test%'
Obviously 'Where * Like' Fails. How can I accomplish this?
You can query all columns in a table like:
select name from sys.columns where object_id = object_id('YourTable')
Then you can construct a query that does a like for each column.
Another approach is to create a calculated column called SearchField that contains a concatenation of all strings you'd like to search for. Then you can search like:
create table #tmp (id int identity, col1 varchar(10), col2 varchar(10),
SearchField as col1 + '|' + col2 persisted)
insert #tmp (col1, col2) values
('alfa', 'beta'),
('gamma', 'DELTA'),
('GAMMA', 'delta')
select * from #tmp where SearchField like '%alfa%'
Try using your SQL query like this.
SELECT * FROM [BTcegeka.C2M].[dbo].[Lookup_Country]
WHERE
COL1 LIke '%test%'
OR COL2 LIke '%test%'
OR COL3 LIke '%test%'
You may use AND instead of OR if your requirement needs that.
If you know the column names at run time, then you should build you query in .NET before passing it to sql. You can build it with the correct column name. This way you can account also for the type of the column you search in.
Careful though this path you chose is prone to SQL injection so before sending a query to the SQL you should check it.
If you really need to do this you can search in sqlserver meta tables and find the description of selected user table. Make a good use of this data is easy and you can make any sql you want with this information, but performance may not the that good
you have to use dynamic sql for implementing this. Your column name needs to be passed as parameter to this stored procedure or if you dont want to create stored procedure just declare one paramter and assign the value selected from the drop down list to it and use that in the query.
create procedure sp_dynamicColumn
(
#columnName varchar(10)
)
as
begin
declare #DYNAMICSQL nvarchar(4000);
SET #DYNAMICSQL = 'Select * from [BTcegeka.C2M].[dbo].[Lookup_Country] where '+ #columnName + ' like ''%test%'''
EXECUTE SP_EXECUTESQL #DYNAMICSQL
end
go