Comparing 2 strings and find out mismatches - sql

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".

Related

SQL / DB2 Array in Where declared in with

anyone does know a workaround for querying with parameters/variables for usage in where [...] in functions on db2 v11?
what i tried:
DECLARE #list varchar(23) = '1,2,3,4'
SELECT ...FROM tbl WHERE col IN (#list)
WITH test(val) AS (VALUES(ARRAY['5','9']))
SELECT ... FROM table, test WHERE col ANY(val)
both do not work, first one isn't db2 compatible, the second ones does not work cause he cant split the values.
any ideas or examples?
Try this:
SELECT t.*
FROM tbl t
WHERE EXISTS
(
select 1
from xmltable
(
'for $id in tokenize($s, ",") return <i>{string($id)}</i>'
passing '1,2,3,4' as "s"
columns
tok int path '.'
) v
where v.tok = t.col
);
You may use a parameter marker instead of the string constant 1,2,3,4 as for usual string paramter, if you want to provide such a list of integers as a comma separated string at runtime.
Declare local temporary table and insert your value list in that ?

SSIS Execute SQL Task contain Insert Into and Select

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

Check if values in an array exist in another array using sql

I want to perform some operations based on, if we have some values in one array existing in another array. Following is part of my code where I am trying to handle the arrays. I have 2 arrays CL_NM[ ] and CL_NM_FIN[ ]. I would want to perform an update if a value in CL_NM[ ] doesn't exist in CL_NM_FIN[ ]. Please help me on how should I modify my code.
Upon trying to do this, I am getting that the column already exists error because the for loop is not going through all elements in CL_NM_FIN[ ] before going into the else condition.
I was able to solve this using the following:
DO
BEGIN
DECLARE arr1 TINYINT ARRAY = ARRAY(1,2,3,4);
DECLARE arr2 INTEGER ARRAY = ARRAY(1,2);
--convert array in table rst1 with column name col1
rst1 = UNNEST(:arr1) as (COL1);
--convert array in table rst2 with column name col1
rst2 = UNNEST(:arr2) as (COL1);
--query with minus
select col1 from :rst1
minus
select col1 from :rst2;
END;

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.