reverse where query in mysql2 - mysql2

I want to find records using like query but in reverse mode
For exa: I have one string ts5e434
And now in databse I have one column called geohash and its contan comma seperated values
1) "ts5e4,ts5,ts5e434"
2) "ab,ye"
3) "ts,thh"
4) "t"
So here I want to get 1, 3 and 4 no records because its partially matching string
exa like clause
SELECT
*
FROM
service_geohashes
WHERE
'ts5e434' LIKE geohashes
Can anyone help me
Thanks in advance

I created function "LikeAny" in MSSQL which looks like:
CREATE FUNCTION [dbo].[LikeAny](#text nvarchar(MAX), #delimiter varchar(20), #comparestring nvarchar(MAX))
RETURNS BIT AS
BEGIN
DECLARE #LikeAny BIT = 0,
#TempString nvarchar(MAX)
DECLARE MY_CURSOR CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT value FROM STRING_SPLIT(#text, #delimiter)
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO #TempString
WHILE ##FETCH_STATUS = 0
BEGIN
--Do something with Id here
IF (#TempString <> '' AND #comparestring LIKE N'%' + #TempString + '%')
BEGIN
SET #LikeAny = 1
BREAK;
END
ELSE
FETCH NEXT FROM MY_CURSOR INTO #TempString
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
RETURN #LikeAny
END
If you use this in your example, it should look like:
SELECT
*
FROM
service_geohashes
WHERE
[dbo].[LikeAny](geohashes ,',', 'ts5e434') = 1
I tried also to convert the function above into MySQL but I had no option to test it on real environment
it looks like:
DROP FUNCTION IF EXISTS LikeAnyCommaDelimited;
DELIMITER $$
CREATE FUNCTION LikeAnyCommaDelimited(p_text longtext, p_comparestring longtext)
RETURNS TINYINT
DETERMINISTIC
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_LikeAny TINYINT DEFAULT 0;
DECLARE v_TempString longtext;
DECLARE v_SQL longtext;
drop temporary table if exists tempa;
drop temporary table if exists tempb;
CREATE TEMPORARY TABLE tempa( txt text );
CREATE TEMPORARY TABLE tempb( val char(255) );
insert into tempa values(p_text);
set v_SQL = concat("insert into tempb (val) values ('", replace(( select group_concat(distinct txt) as data from tempa), ',', "'),('"),"');");
prepare statement1 from #sql;
execute statement1;
DEClARE split_cursor CURSOR FOR
SELECT value FROM (select distinct(val) as value from tempb);
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN split_cursor;
get_string: LOOP
FETCH split_cursor INTO v_TempString;
IF v_finished = 1 THEN
LEAVE get_string;
END IF;
IF (v_TempString <> '' AND p_comparestring LIKE N'%' + CONCAT(v_TempString , '%') THEN
BEGIN
SET v_LikeAny = 1;
LEAVE get_string;
END
END LOOP get_string;
CLOSE split_cursor;
END$$
DELIMITER ;
Let me know if you have any issues.

Related

Can I create a table with columns named similar to field value of another table, return by SELECT statement

Question Image
When I execute this script, there is a syntax error. What is wrong with this?
use TEST
go
CREATE TABLE newTagsTable
(
(SELECT TEST.dbo.dynamicTags.Alais
FROM TEST.dbo.dynamicTags
WHERE ID = 2) varchar(200)
);
Is this what you need ?
SELECT Alais
into newTagsTable
FROM dynamicTags
WHERE ID = 2;
DEMO
Ok, so something like this then:
create procedure test_proc
as
declare #p_sql varchar(2000);
declare #p_sql_2 varchar(2000);
declare #getid CURSOR;
SET #getid = CURSOR FOR
SELECT Alais
FROM dynamicTags;
begin
set #p_sql = 'create table newTagsTable (';
OPEN #getid
FETCH NEXT
FROM #getid INTO #p_sql_2
WHILE ##FETCH_STATUS = 0
begin
set #p_sql = #p_sql + #p_sql_2 + ' varchar(20),'
FETCH NEXT FROM #getid INTO #p_sql_2
end;
set #p_sql = left(#p_sql, len(#p_sql)-1) + ')';
EXEC (#p_sql);
end;
And then just execute the procedure:
exec test_proc
You can add parameters to this to make it more usable for orher situations...
Here is the demo for this second option:
DEMO

SQL Iterating Select Statement

In my Database I have various Schemas & every Schema have a Table as [Company] & Other Tables.
I have written below Query which iterates all Schemas & in case i want to INSERT something in a Table for all Schemas I run this Query.
I am stuck in a Scenario where Insert Query requires Values from a [Company] Table.
Example - In 1 Schema I have [Company] Table & I have 4 Records in it.
So I want to INSERT 4 Records in [Menu] Table & Company Id will be picked from [Company] Table.
Right Now, In the below Query I am just Selecting Id from [Company] table.
I want to know How to iterate through the Records of Select Statement?
-- in-memory schema table to hold distinct schema_names
DECLARE #i int
DECLARE #numrows int
DECLARE #schema_names nvarchar(max)
DECLARE #schema_table TABLE (
idx smallint Primary Key IDENTITY(1,1)
, schema_names nvarchar(max)
)
DECLARE #company_table nvarchar(max)
DECLARE #sql nvarchar(max)
-- populate schema table
INSERT #schema_table
SELECT name FROM sys.schemas Where name <> 'dbo' AND name <> 'guest' AND name <> 'INFORMATION_SCHEMA' AND name <> 'db_accessadmin' AND name <> 'db_backupoperator' AND name <> 'db_datareader' AND name <> 'db_datawriter' AND name <> 'db_ddladmin' AND name <> 'db_denydatareader' AND name <> 'db_denydatawriter' AND name <> 'db_owner' AND name <> 'db_securityadmin' AND name <> 'sys'
select * from #schema_table
-- enumerate the table
SET #i = 1
SET #numrows = (SELECT COUNT(*) FROM #schema_table)
IF #numrows > 0
WHILE (#i <= (SELECT MAX(idx) FROM #schema_table))
BEGIN
-- get the next record primary key
SET #schema_names = (SELECT schema_names FROM #schema_table WHERE idx = #i)
SET #company_table = '['+#schema_names+'].[Company]'
SET #sql = 'select Id from ' + #company_table
EXEC(#sql)
BEGIN TRY
DECLARE #sSQL nvarchar(500);
SELECT #sSQL = N'INSERT ['+#schema_names+'].[Menu] VALUES (9, N''Dashboard'', N''Charts'', N''/Dash/Chart'', 1)'
EXEC sp_executesql #sSQL
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()+' '+#schema_names AS ErrorMessage;
END CATCH
-- increment counter for next record
SET #i = #i + 1
END
In this Query - 9 will be replaced by Value from [Company] Table.
Just it simple for iterating in each row you can use the below Example
CREATE PROCEDURE cursor1()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE fname1 CHAR(20) DEFAULT "";
DECLARE lname1 CHAR(20) DEFAULT "";
DECLARE nameList CHAR(100) DEFAULT "";
-- 1. Declare cursor for employee
DECLARE emp_cursor CURSOR FOR SELECT fname, lname FROM employee WHERE salary > 40000;
-- 2. Declare NOT FOUND handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
-- 3. Open the cursor
OPEN emp_cursor;
L: LOOP
-- 4. Fetch next tuple
FETCH emp_cursor INTO fname1, lname1;
-- Handler will set finished = 1 if cursor is empty
IF finished = 1 THEN
LEAVE L;
END IF;
-- build emp list
SET nameList = CONCAT( nameList, fname1, ' ', lname1, ';' );
END LOOP ;
-- 5. Close cursor when done
CLOSE emp_cursor;
SELECT nameList ;
END //
DELIMITER
Eg2.
DROP PROCEDURE IF EXISTS depreciation_calculator;
# depreciation calculator..........................................
CREATE PROCEDURE depreciation_calculator(IN deprcesionDate INT)
BEGIN
DECLARE acc DOUBLE;
DECLARE diff INT;
DECLARE currentDate DATE;
DECLARE depDate VARCHAR(12);
DECLARE dep DOUBLE;
DECLARE bookValue DOUBLE;
DECLARE assetId INT;
DECLARE depStatus VARCHAR(12);
DECLARE finished INTEGER DEFAULT 0;
DECLARE emp_cursor CURSOR FOR SELECT
dep_date,
dep_amount,
dep_status,
asset_ass_id,
book_value,
accumulative_value
FROM depreciation;
-- 2. Declare NOT FOUND handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
-- 3. Open the cursor
OPEN emp_cursor;
L: LOOP
-- 4. Fetch next element
FETCH emp_cursor
INTO depDate, dep, depStatus, assetId, bookValue, acc;
-- Handler will set finished = 1 if cursor is empty
IF finished = 1
THEN
LEAVE L;
END IF;
SET currentDate = DATE(now());
SET diff := TIMESTAMPDIFF(MONTH, depDate, currentDate);
IF diff > 12 && diff <= 13 && bookValue > 0
THEN
SET depDate = currentDate;
SET dep = dep;
SET acc = acc + dep;
SET bookValue = bookValue - dep;
IF bookValue = 0
THEN
SET depStatus = 'depreciated';
END IF;
INSERT INTO depreciation (dep_date, dep_amount, dep_status, dep_description, dep_commnet, asset_ass_id, book_value, accumulative_value)
VALUES (depDate, dep, depStatus, 1, 1, assetId, bookValue, acc);
END IF;
END LOOP;
-- 5. Close cursor when done
CLOSE emp_cursor;
SELECT diff;
END;

UDF replace function - failing to recognize strings

I am trying to replace names found in 'xml' fieldname as hyperlinks, by matching with the names in database_tags.
I have created a simple UDF, but it does not execute the query correctly, as it creates duplicate name tags within the XML fieldname.
ALTER FUNCTION [dbo].[Tags](#XML VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
SELECT #XML = REPLACE(#XML,[Name],''+[name]+'')
FROM [dbo].[database_tags]
where UploadDate >= '2014-09-01'
RETURN #XML
END
UPDATE:
I manage to update my function to the following below, however the function only is only recognizing one name from the XML fieldname data.
DECLARE #N VARCHAR(MAX)
SELECT #N = [Name] FROM [dbo].[database_tags]
WHERE #XML LIKE '%'+[Name]+'%'
AND UploadDate >= '2014-09-01'
IF #N IS NOT NULL
BEGIN
SELECT #XML = REPLACE(#XML,
#N,
''+#N+'')
END
RETURN #XML
END
Please advice further if possible. Many thanks
You can use a cursor to loop through values in the table replace each name with the hyper link. But replace can force unwanted outcome. For example if a configured name is part of a separate string function will replace it with a hyperlink.
Create FUNCTION [dbo].[ReplaceTags](#XML VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #Name VARCHAR(MAX)
DECLARE CUR CURSOR FAST_FORWARD FOR
SELECT name
FROM database_tags
Where UploadDate >= '2014-09-01'
OPEN CUR
FETCH NEXT FROM CUR INTO #Name
WHILE ##FETCH_STATUS = 0
BEGIN
IF #Name IS NOT NULL
BEGIN
SELECT #XML = REPLACE(#XML,
#Name,
''+#Name+'')
END
FETCH NEXT FROM CUR INTO #Name
END
CLOSE CUR;
DEALLOCATE CUR;
RETURN #XML
END

Passing data into nested cursors in TSQL

I have a cursor that gets data and fetches it into #data_table. Then in the while loop I want to pass that #data_table into another cursor (as the table name) to run some more processing. I keep getting a declare #data_table error. How do I fix this?
DECLARE #var_name varchar(50)
DECLARE #data_table varchar(50)
DECLARE #data_value varchar(50)
DECLARE curDiscreteVars CURSOR LOCAL
FOR SELECT DISTINCT v.var_name, v.data_table
FROM dbo.vars v
GROUP BY v.var_name, v.data_table
-- Loop through cursor, translating variable values as needed, and generate counts for each val_code for a variable
OPEN curDiscreteVars
FETCH NEXT FROM curDiscreteVars
INTO #var_name, #data_table
WHILE ##FETCH_STATUS = 0
BEGIN
--loop through all possible data values
DECLARE curValues CURSOR LOCAL
FOR SELECT DISTINCT #var_name
FROM #data_table
OPEN curValues
FETCH NEXT FROM curValues
INTO #data_value
WHILE ##FETCH_STATUS = 0
BEGIN
print #var_name
FETCH NEXT FROM curValues
INTO #data_value
END
CLOSE curValues
DEALLOCATE curValues
FETCH NEXT FROM curDiscreteVars
INTO #var_name, #data_table
END
CLOSE curDiscreteVars
DEALLOCATE curDiscreteVars
For my part, i don't like cursors! For me cursors are evil. The give you locks and such that you don't want.
What i always do is create a temp table with the values (like you normally insert into the cursor) and loop through it with a while loop
like this :
declare #currow int
, #totrow int
create table #tmp_values (id int identity(1, 1), val int)
insert
into #tmp_values
select val
from tableX
set #totrow = ##rowcount
set #currow = 1
while #totrow > 0 and #currow <= #totrow
begin
select #val = val
from #tmp_values
where id = #currow
set #currow = #currow + 1
end
That way you have more control of things and you can re-use the tmp table
I'm not sure I understand what you're talking about doing, but variables cannot be used as table names. Or, really anything that's not a field name. You'll need to use dynamic SQL. That is, assign your SQL string to a variable, an then run EXEC() command.
For example:
DECLARE #sqlcmd varchar(max)
DECLARE #table_name sysname
DECLARE cur_tables FOR
SELECT name FROM sys.tables
OPEN cur_tables
FETCH NEXT FROM cur_tables INTO #table_name
WHILE ##FETCH_STATUS = 0 BEGIN
SET #sqlcmd = 'SELECT TOP 10 * FROM ' + QUOTENAME(#table_name)
EXEC ( #sqlcmd )
FETCH NEXT from cur_tables INTO #table_name
END
CLOSE cur_tables
DEALLOCATE cur_tables
Alternately, if what you mean is that you need a location to store the data that is like a table, then create a temporary tabled for it.

How to convert varchar to numbers in sql developer

I trying to use list of numbers like this.
SELECT *
FROM users
WHERE id in (list_of_ids)
this is part of sql procedure and the variable 'list_of_ids' is varchar and it contains id's like this: 1,2,3,4,5........
How can i use this list and this query
Try this as well. This could be the better solution as it wont require any additional function to create.
oracle regexp_substr will split comma seperated values into different rows and passes to query.
SELECT *
FROM users
WHERE id in
(SELECT regexp_substr(list_of_ids,'[^,]+', 1, level) FROM dual
connect by regexp_substr(list_of_ids, '[^,]+', 1, level) is not NULL)
You can use a ref cursor to construct the sql query, as in this pl/sql block:
declare
list_of_ids varchar2(100) := '1,3,4'; -- example
c_cursor sys_refcursor;
result number;
begin
open c_cursor for ( 'SELECT id '||
'FROM users '||
'WHERE id in ('||list_of_ids||')'
);
fetch c_cursor into result;
while c_cursor%found
loop
dbms_output.put_line('ID='||to_char(result));
fetch c_cursor into result;
end loop;
close c_cursor;
end;
/
Try this solution in your project.
Add a new user function that returns a table.
Code is below:
CREATE FUNCTION [dbo].[fn_Split](#text varchar(8000), #delimiter
varchar(20) = ' ')
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
And then call it from your stored procedure like below.
DECLARE #list_of_ids AS VARCHAR(100)
SET #list_of_ids = '1,2,3,4,5,6,7,8,9,10,'
SELECT *
FROM users
WHERE id in (SELECT value FROM dbo.fn_Split(#list_of_ids,','))