Is there a way to replace multiple substrings in a single mysql column field?
In my result, there are fields like:
'&DY, &Q3'
In this case, DY and Q3 are match codes which I have to replace with a defined Word.
I tried to work with this regex_replace function
CREATE FUNCTION `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000)) RETURNS varchar(1000)
DETERMINISTIC
BEGIN
DECLARE temp VARCHAR(1000);
DECLARE ch VARCHAR(1);
DECLARE i INT;
SET i = 1;
SET temp = '';
IF original REGEXP pattern THEN
loop_label: LOOP
IF i>CHAR_LENGTH(original) THEN
LEAVE loop_label;
END IF;
SET ch = SUBSTRING(original,i,1);
IF NOT ch REGEXP pattern THEN
SET temp = CONCAT(temp,ch);
ELSE
SET temp = CONCAT(temp,replacement);
END IF;
SET i=i+1;
END LOOP;
ELSE
SET temp = original;
END IF;
RETURN temp;
END
My SQL Query:
SELECT REGEX_REPLACE(fm.column,'(\&[\w]{2})*','My Word') FROM `table` fm WHERE id = '123'
didn't work. Maybe one problem is, that my substrings begin with "&" which is an operator in regex!?
try this, but i have use MariaDB they have REGEX_REPLACE internal
https://mariadb.com/kb/en/mariadb/regexp_replace/
SELECT REGEXP_REPLACE('&DY, &Q3','\(\&[A-Z0-9]+\),*','My Word');
Result:
My Word My Word
Related
In the code below, there's a function that generates a random string, and a procedure that is supposed to insert random strings into a table called Users. I have successfully created the function and it's working without any problem, but when I try to create the procedure, it returns a syntax error at line "SET #str = SELECT randstring(8);" I think I am trying to call my function in a wrong way. I'm new to databases so please bear with me.
DELIMITER $$
CREATE FUNCTION `Randstring`(LENGTH SMALLINT(3)) RETURNS VARCHAR(100) CHARSET utf8
BEGIN
SET #returnStr='';
SET #allowedChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
SET #i = 0;
WHILE (#i < LENGTH) DO
SET #returnStr = CONCAT(#returnStr, SUBSTRING(#allowedChars, FLOOR(RAND() * LENGTH(#allowedChars) + 1), 1));
SET #i = #i + 1;
END WHILE;
RETURN #returnStr;
END
DELIMITER $$
CREATE PROCEDURE insertdata()
BEGIN
SET #str='';
DECLARE i INT DEFAULT 0;
WHILE i <= 1000 DO
SET #str = SELECT randstring(8);
INSERT INTO Users (user_name)
VALUES(#str);
SET i = i + 1;
END WHILE;
END $$
DELIMITER ;
Presumably, you intend either:
SET #str = randstring(8);
Or:
SELECT #str := randstring(8);
Or:
SET #str = (SELECT #randstring(8));
A SELECT when used as a subquery needs a parentheses before it. However, no subquery is really necessary.
I want to search in Wp post(title) column and delete entries which contains words longer then 10 characters but i am unable to find a query to do that. can anyone help?
Edit: I made following SP.
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `p`(IN `instring` VARCHAR(255))
begin
declare tempstring varchar(10000);
declare idin int;
declare outstring varchar(100);
declare c1 varchar(100);
declare c2 varchar(100);
declare totallength int DEFAULT 0;
declare checkit int;
declare done int;
DECLARE CUR1 CURSOR for SELECT id,post_title FROM wp_posts;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
drop table if exists occursresults;
create table occursresults (col1 varchar(20), col2 varchar(20),totallength int );
open CUR1;
read_loop: LOOP
FETCH CUR1 INTO idin,tempstring;
if done then leave read_loop; end if;
set checkit = 0;
looper: while tempstring is not null and instr(tempstring,' ') > 0 do
set checkit = checkit + 1;
if checkit > 100 then #In case of infinite loop
leave looper;
end if;
set outstring = substr(tempstring,1,instr(tempstring, ' ') - 1);
set tempstring = ltrim(rtrim(replace(tempstring,concat(outstring,' '),'')));
set c1 = substr(outstring,1,instr(outstring, ' ') - 1);
set c2 = replace(outstring,concat(c1,' '),'');
if Length(c2) > 10 then
delete from wp_posts where id=idin;
end if;
if Length(c2) < 10 then
INSERT INTO occursresults (COL1,COL2,totallength) VALUES (c1,c2,Length(c2));
end if;
end while;
select tempstring;
set outstring = tempstring;
set c1 = substr(outstring,1,instr(outstring, ' ') - 1);
set c2 = replace(outstring,concat(c1,' '),'');
if Length(c2) > 10 then
delete from wp_posts where id=idin;
end if;
if Length(c2) < 10 then
INSERT INTO occursresults (COL1,COL2,totallength) VALUES (c1,c2,Length(c2));
end if;
end loop;
close cur1;
end$$
DELIMITER ;
but when i call it. i get this error.
Error
Static analysis:
1 errors were found during analysis.
Missing expression. (near "ON" at position 25)
SQL query: Edit Edit
SET FOREIGN_KEY_CHECKS = ON;
MySQL said: Documentation
2014 - Commands out of sync; you can't run this command now
You can use a regex to identify the rows to delete:
DELETE FROM post
WHERE title RLIKE '[a-zA-Z]{10}'
This defines a word as a sequence of alphabetic characters. You might want to adapt the regex to add more characters if needed (digits, underscore, dash, ...).
you can use CHAR_LENGTH as a function to get the length.
Select:
SELECT
*
FROM
post
WHERE
CHAR_LENGTH(title) > 10;
Delete query:
DELETE FROM post
WHERE
CHAR_LENGTH(title) > 10;
Note: LENGTH function too works but it will calculate in bytes rather than chars more info on this refer this MySQL - length() vs char_length()
I have a field text, In it there is information about such
sch hcbhsc hscbshcbc xxxxxxxx sgxfag jdhajdh;
dchbdbc bdcbdh bchdbd xx/xx-xxxx/xx svdhs sbjbsc
bdchbdc jncjdnc jbcjb xx/xx-xxxxx/xx gcvsgc jcbjsb
dchjbd bhjcbdcb bdcbcd xx-xxxx/xx shchscv hscbhsc
dhcbhd jdcbjdb jdcnjdcn xx-xxxxx/xx shcvsch jbscjc
Place x is only a digit, I need to write select and only those numbers are taken
Use SUBSTRING and PATINDEX string functions IN SQL server :
SELECT SUBSTRING(Your_FieldName, PATINDEX('%[0-9]%', Your_FieldName),
LEN(Your_FieldName))
For MYSQL refer below URL :
Query to get only numbers from a string
string
There is no formal PATINDEX() function in MySQL that achieves both the regex pattern lookup with returned character index, define User-Defined function that loops through each character in the length of a string and checks a REGEXP pattern on the character. Once created, use such a function in-line of a query.
DROP FUNCTION IF EXISTS PatIndex;
DELIMITER $$
CREATE FUNCTION PatIndex(pattern VARCHAR(255), tblString VARCHAR(255)) RETURNS INTEGER
DETERMINISTIC
BEGIN
DECLARE i INTEGER;
SET i = 1;
myloop: WHILE (i <= LENGTH(tblString)) DO
IF SUBSTRING(tblString, i, 1) REGEXP pattern THEN
RETURN(i);
LEAVE myloop;
END IF;
SET i = i + 1;
END WHILE;
RETURN(0);
END
Here is a MySQL function (routine) that will do just that. It is an improved version from the solution given here: how-to-get-only-digits-from-string-in-mysql
This improved version can handle much larger numbers. The old solution was limited by the INTEGER value, so if you had phone numbers for example (or string containing many digits), it would fail with out of range for column.
DELIMITER $$
CREATE FUNCTION ExtractNumber (in_string VARCHAR(50))
RETURNS varchar(50)
NO SQL
BEGIN
DECLARE ctrNumber VARCHAR(50);
DECLARE finNumber VARCHAR(50) DEFAULT '';
DECLARE sChar VARCHAR(1);
DECLARE inti VARCHAR(50) DEFAULT 1;
IF LENGTH(in_string) > 0 THEN
WHILE(inti <= LENGTH(in_string)) DO
SET sChar = SUBSTRING(in_string, inti, 1);
SET ctrNumber = FIND_IN_SET(sChar, '0,1,2,3,4,5,6,7,8,9');
IF ctrNumber > 0 THEN
SET finNumber = CONCAT(finNumber, sChar);
END IF;
SET inti = inti + 1;
END WHILE;
RETURN CAST(finNumber AS UNSIGNED);
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;
Now you can do this:
SELECT ExtractNumber(my_field)
FROM my_table;
I have some JSON-objects and I need to fetch property values for them.
My situation is based on this query:
DO $$
DECLARE
v_whatever character varying := 'a';
v_res character varying;
BEGIN
SELECT params->>v_whatever FROM user_info1 WHERE uid = 9 INTO v_res;
RAISE NOTICE 'v_res: %', v_res ;
END; $$
In table, value for column params(type json) is: {"a":"b","b":"c","c":"d"} ,
Query returns v_res: b
Because I don't have specific property names, code looks like this:
DECLARE
v_temp char varying;
v_obj char varying[];
comp char varying[];
BEGIN
SELECT json_object_keys(params) FROM user_info1 WHERE uid = p_uid into v_temp;
SELECT params->>v_temp FROM user_info1 WHERE uid = 9 INTO v_obj;
A basic plpgsql FOR loop:
DO
$$
DECLARE
v_whatever text := 'a';
v_res text;
BEGIN
FOR v_res IN
SELECT params->>v_whatever
FROM user_info1
WHERE uid = 9
LOOP
RAISE NOTICE 'v_res: %', v_res;
END LOOP;
END;
$$
Note that a set-based approach is often more efficient than looping. Look to unnest() ..
I want to create a table dynamical but my built string to create the table is NULL - why?
The goal is to get column values from an existing table and create a new table with columns named with these values.
DELIMITER $$
DROP PROCEDURE IF EXISTS fanart_test.get_incomplete_artwork $$
CREATE PROCEDURE fanart_test.get_incomplete_artwork()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE type_id INT;
DECLARE type_name INT;
DECLARE build_string VARCHAR(20000);
DECLARE cursor1 CURSOR FOR
SELECT type_id,type_name FROM fanart_types WHERE type_section = 3;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN cursor1;
get_results: LOOP
FETCH cursor1 INTO type_id, type_name;
IF finished = 1
THEN LEAVE get_results;
END IF;
IF build_string = ""
THEN SET build_string = CONCAT('CREATE TABLE `tmp_incomplete_artwork`(`', type_name, '` TEXT');
ELSE SET build_string = CONCAT(build_string,',', type_name);
END IF;
SET build_string = CONCAT(build_string,')');
END LOOP get_results;
CLOSE cursor1;
SET #s = build_string;
PREPARE build FROM #s;
EXECUTE build;
DEALLOCATE PREPARE build;
END $$
DECLARE build_string VARCHAR(20000);
The build_string is not set to anything initially, so it'll probably be NULL.
IF build_string = ""
This will never return true, since NULL = "" is not true.
ELSE SET build_string = CONCAT(build_string,',', type_name);
Concatenating any string with NULL returns NULL.
Re your comment:
You have named your variables type_id and type_name which are the same as your column names in your table. This creates an ambiguity, and it turns out that MySQL prefers to interpret the identifiers as the local variables, instead of column names.
So this:
SELECT type_id,type_name FROM fanart_types WHERE type_section = 3;
Will return the current value of type_id and type_name, which is uninitialized, i.e. NULL. Therefore a pair of NULLs are returned for all rows of the table.
Just rename the variables to be distinct from your table's column names, or else qualify the columns so they are clearly columns instead of variables:
SELECT f.type_id, f.type_name FROM fanart_types f WHERE f.type_section = 3;
Also you probably want to declare type_name as TEXT instead of INT.