How to replace a string with values from columns in a table in SQL - sql

I have a table like the following
Exp Major Start
---------------------------------- ----------- -------
My names ar W.Major and W.Start Hal Bark
W.Major is a doctor Mark Slope
I want to write a SQL query to replace W.Major or W.start in the exp column with the values in the columns Major and Start.
Can someone please suggest me a way to do this?

The key is using two replace functions.
Update tablename
set exp = replace (replace (exp, 'W.Major', major), 'W.Start', start);
Read more about replace on MSDN. This function is more or less the same across all major RDBMSes.
EDIT:
In a scenario where you don't know how many keywords and replacement columns are there in your text, I'd suggest you create a stored procedure in which you do the following:
Use a temporary table that has two columns- one for the search key, e.g. 'W.Major', and the other with the name of the column , e.g. 'major'. Note that you don't have to store the values from that column, just the name of the column. Like this:-
key replacement_col
---------- -----------------
W.Major major
W.Start start
... and so on.
Now build a dynamic SQL looping in with your main table and this temporary table. Loop the way you find comfortable. I would suggest the following method of looping:
a) From the first row to the last row in your main table, select the column exp.
b) Loop through this value of exp to search for any search keywords. Look for the keywords and values in your temp table.
c) Prepare a dynamic SQL statement which would then write an update query with nested replace calls for you. Execute this dynamic SQL.

Related

Complicated text compare in SQL

Suppose I have a table result
---------------------------------------------------------
coupon id| required_product_ids|used_product_in_this_year
---------------------------------------------------------
1 |1,2,3,10 |2,3,4,5,6,7,8,9,10,12,13
How can I check if used_product_in_this_year has at least one required_product_ids by SQL.
I tried somethings with SQL like keyword but did not success.
There is no native SQL construct for performing this type of comparison.
To find a single value in a comma separated list, MySQL provides a FIND_IN_SET function. But to handle a comma separated list of values, to check each one, to see if it's in a list, each separate value would need to be supplied into FIND_IN_SET. And that would be unweildy.
If the hard and fast requirement is to handle this comparison in a SQL statement, I'd recommend writing a function to do the comparison.
DELIMITER $$
CREATE FUNCTION upity_halo_rpi(upity VARCHAR(4000), rpi VARCHAR(4000))
RETURNS INT DETERMINISTIC
BEGIN
-- TODO: extract first element of upity
-- TODO: check if element is in rpi list
-- if it is found in the list
RETURN TRUE;
-- otherwise, split off next element
-- loop through all elements
-- if loop completes without finding a match is found, fall out
RETURN FALSE;
END$$
DELIMITER ;
With the function written, and thoroughly tested, it could be used in a SQL statement. To return a column that indicates that the row "has at least one"...
SELECT t.coupon id
, t.required_product_ids
, t.used_product_in_this_year
, upity_halo_rpi(t.used_product_in_this_year,t.required_product_ids) AS halo
FROM result t
To return:
coupon id required_product_ids used_product_in_this_year halo
--------- -------------------- ------------------------ -----
1 1,2,3,10 2,3,4,5,6,7,8,9,10,12,13 1
I'm not going to write the function. I'm just demonstrating a possible approach. One possible answer to "how" this type of comparison operation could be performed within a SQL statement.
This is how you can do it, without changing your database structure.
In MYSQL (Tested):
select * from TableName
where concat(',', used_product_in_this_year, ',') regexp concat(',',replace(required_product_ids,',',',|,'),',')
Using this Regex structure with your table and manipulating the data with a some mysql string functions.
I don't recommend your database structure, but I like puzzles and this one was fun, thanks for the challenge.

Transferring several similar named tables in SSIS

I want to create an interface between 2 databases on SQL Server 2008+ to copy several similar named tables into one.
I have n tables that all have the same naming convention, for example:
SalesInvoicePlanning2014ver1
SalesInvoicePlanning2015ver1
SalesInvoicePlanning2015ver2
etc.
The numbers can vary and do not have a set start (or end), but are always of the "int"-Datatype.
I also have a table "tabledir" that contains all table names as list. (one field) There are a total of 30-40 entries in that list with (for me) undesired entries. In the above example I would need 3 of the 30 tables.
The plan is to use a loop container to
select Top 1([name]) from [tabledir] where name like 'SalesinvoicePlanning%'
and then use the result as variable in the following SSIS Data transfer task:
Select * from [variable]
However, I'm stuck with the SQL statement to give me the desired tablename on each iteration.
Performance is not really an issue. Any advice? Am I wrong trying to use a loop-container?
You can follow below steps -
Step 1 - You can first create SQL task to get all table names into one variable lets say, TableNames of type Object(recordset) using you query.
e.g. select ([name]) as TableName from [tabledir] where name like 'SalesinvoicePlanning%'
Step 2 - Add foreach loop container to iterate over this variable TableNames to take single table name into new variable current_table and add data flow into the container to import data to destination table. Your source query will be expression like -
Select column_names from current_table

Oracle - How to make auto-increment column with varchar type?

In my assignment with Oracle 11g, I am asked to make a table with column has this structure:
[NL|TE|][0-9]^10
Where NL or TE is inputed when INSERT row and [0-9]^10 is an auto-increment 10 digits number.
Example:
NL1234567890 or TE0253627576
When INSERT, the user should only write this:
INSERT INTO TableA VALUES ('NL');
And the DBMS take care of the rest. So how can I do so? Im still a newbie in this thing.
CREATE SEQUENCE your_seq;
/
CREATE OR REPLACE TRIGGER your_tablename_BI
BEFORE INSERT
ON your_tablename
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
:NEW.your_col := :NEW.your_col || trim(to_char(your_seq.nextval, '0000000000'));
END your_tablename_BI;
/
Sample code?
'NL' || to_char(yoursequence.nextval)
I would keep them as separate columns. One is a VARCHAR2 that takes NL or whatever, the other is a NUMBER which is populated by the sequence.
You can then concatenate them at query time (put it in a view if you want) or use a virtual column.
Why? I can almost guarantee you that at some point you'll have a requirement to query the table on the character portion, or the numeric portion, or to sort on one or the other. Since you kept them separate, this is easy. If you had squashed them into a single column, you would have had to parse the values out at query time which leads to more complicated code than you need.

Stored procedure that takes list of string as input and insert missing rows then return them

I have a table Names
Id Name
+----+---------------+
1 John
2 Kate
3 Mark
I want to create a stored procedure that does the following:
1) take a list of names as string as an input parameter
I have done some researches about this but couldn't find the best way to do it. I will call the stored procedure from the entity framework in a C# application. I was thinking of passing the names in one string separated with a comma and the split them in the procedure. But can't figure out how this is done.
2) for each name in the list, if the name does not exist in the Name column, insert a new row for it.
How can I do a switch case if it exists and insert it if not
3) Select * rows that are in the input list.
After adding all the missing Names, I want to select all the names that were in the input list with their id
Can this be done in one stored procedure, or do I have to divide them into multiple.
I am looking for hints on how to do each step, and if they can be combined.
Thanks
Keep your DB side lean and leave logic on the app side, especially if you have grumpy DBA's.
Use a MERGE/Upsert instead.
Check out this SO post.
If you pass a comma delimited list into a stored procedure as a parameter, you are going to need to understand how to use charindex, left, substring and right
As you split out each name - you would add them into a temporary table or a table valued variable.
Your decision about whether to insert the new names into the Names table would be made using an exists() subquery on an insert statement.
You could then, finally, fashion a select statement to join your temp table/table valued variable back to your Names table to pull out all of the keys (including the new ones) and pass them back to your front end.

SQL Query: Modify records based on a secondary table

I have two tables in a PostgreSQL database.
The first table contains an ID and a text field with up to 200 characters and the second table contains a data definition table which has a column that contains smileys or acronyms and a second column which converts them to plain readable English.
The number of records in table 1 is about 1200 and the number in table two is about 300.
I wish to write a SQL statement which will convert any text speak in column 1 in table one into normal readable language based on the definitions in Table 2.
So for example if the value in table 1 reads as: Finally Finished :)
The transformed SQL would be something like: Finally Finished Smiles or smiling,
where the definition is pulled from the second table.
Note the smiley could be anywhere in the text in column one and could one of three hundred characters.
Does anyone know if this is possible?
Yes. Do you want to do it entirely in SQL, or are you writing a brief bit of code to do this? I'm not entirely sure of how to do it all in SQL but I would consider something like what is below:
SELECT row.textToTranslate FROM Table_1
oldText = row.textToTranslate
Split row.textToTranslate by some delimeter
For each word in row.textToTranslate:
queryResult = SELECT FROM Table_2 WHERE pretranslate=word
if(queryResult!=Null)
modifiedText = textToTranslate.replace(word, queryResult)
UPDATE Table_1 SET translatedText=modifiedText WHERE textToTranslate=oldText