Populate ComboBox with Title Case Query Result - ms-access

with TdmBCElections.Create(Self) do
begin
with dmBCElections, qryParties do
begin
SQL.Clear;
if rgpParty.ItemIndex = 0 then
SQL.Text := 'SELECT StrConv(P_Surname, 3), StrConv(P_Names, 3) ' +
'FROM Parties WHERE P_Type = "HEAD"'
else
SQL.Text := 'SELECT StrConv(P_Surname, 3), StrConv(P_Names, 3) ' +
'FROM Parties WHERE P_Type = "TEACHER"';
Open;
while not Eof do
begin
cmbDetails.Items.Add(qryParties['StrConv(P_Surname, 3)'] + ', ' +
qryParties['StrConv(P_Names, 3)']);
Next;
end;
end;
end;
The code above gives me the following error message:
How do I call the table fields when StrConv is applied to them?

You can assign an alias to the fields:
with TdmBCElections.Create(Self) do
begin
with dmBCElections, qryParties do
begin
if rgpParty.ItemIndex = 0 then
SQL.Text := 'SELECT StrConv(P_Surname, 3) as ConvertedSurname, StrConv(P_Names, 3) as ConvertedNames ' +
'FROM Parties WHERE P_Type = "HEAD"'
else
SQL.Text := 'SELECT StrConv(P_Surname, 3) as ConvertedSurname, StrConv(P_Names, 3) as ConvertedNames ' +
'FROM Parties WHERE P_Type = "TEACHER"';
Open;
while not Eof do
begin
cmbDetails.Items.Add(qryParties['ConvertedSurname'] + ', ' +
qryParties['ConvertedNames']);
Next;
end;
end;
end;
Otherwise, you can use field indexes instead of names:
with TdmBCElections.Create(Self) do
begin
with dmBCElections, qryParties do
begin
if rgpParty.ItemIndex = 0 then
SQL.Text := 'SELECT StrConv(P_Surname, 3), StrConv(P_Names, 3) ' +
'FROM Parties WHERE P_Type = "HEAD"'
else
SQL.Text := 'SELECT StrConv(P_Surname, 3), StrConv(P_Names, 3) ' +
'FROM Parties WHERE P_Type = "TEACHER"';
Open;
while not Eof do
begin
cmbDetails.Items.Add(qryParties.Fields[0].AsString + ', ' + qryParties.Fields[1].AsString);
Next;
end;
end;
end;
Either way, I suggest you consider using a parameterized query instead:
SQL.Text := 'SELECT ... FROM Parties WHERE P_Type = :PType';
if rgpParty.ItemIndex = 0 then
Parameters.ParamByName('PType').Value := 'HEAD'
else
Parameters.ParamByName('PType').Value := 'TEACHER';

Related

Showing first and last name in statusbar

I am a beginner in Delphi, and I would like to show first and last name in the StatusBar instead of the username.
Here is my code:
procedure TForm1.Button1Click(Sender: TObject);
begin
with Login do
begin
active := false;
sql.Clear;
sql.Text := 'SELECT korisnicko, lozinka from operateri where korisnicko = ' + quotedstr(edtkorisnicko.Text) + ' and lozinka = ' + quotedstr(edtlozinka.Text);
active := true;
if Login.RecordCount <> 0 then
begin
form1.Hide();
form2.statusbar1.panels[0].text:= 'Korisnik: ' + edtKorisnicko.Text;
form2.showmodal();
end
else
begin
ShowMessage('Korisničko ime ili lozinka nisu validni!');
end;
end;
"Korisnicko or edtKorisnicko" standing for "username".
Given that your own answer shows the desired name is stored in the ime_prezime field of the database record you are searching for, you can simply retrieve that field in the very same SELECT query that is searching for the username/password, there is no need to run a 2nd query to get that field value separately, eg:
procedure TForm1.Button1Click(Sender: TObject);
begin
Login.Close;
Login.SQL.Text := 'SELECT ime_prezime from operateri where korisnicko = ' + QuotedStr(edtkorisnicko.Text) + ' and lozinka = ' + QuotedStr(edtlozinka.Text);
Login.Open;
Login.First;
if not Login.Eof then
begin
Form1.Hide();
Form2.StatusBar1.Panels[0].Text := 'Korisnik: ' + Login.FieldByName('ime_prezime').AsString;
Form2.ShowModal();
end
else
begin
ShowMessage('Korisničko ime ili lozinka nisu validni!');
end;
end;
There is answer. :)
procedure TForm1.Button1Click(Sender: TObject);
begin
with Login do
begin
active := false;
sql.Clear;
sql.Text := 'SELECT korisnicko, lozinka from operateri where korisnicko = ' + quotedstr(edtkorisnicko.Text) + ' and lozinka = ' + quotedstr(edtlozinka.Text);
active := true;
if Login.RecordCount <> 0 then
begin
active := false;
sql.Clear;
sql.Text := 'SELECT ime_prezime FROM operateri WHERE korisnicko = ' + quotedstr(edtkorisnicko.Text);
active := true;
form1.Hide();
form2.statusbar1.panels[0].text := 'Korisnik: ' + Login.FieldByName('ime_prezime').Text;
form2.showmodal();
end
else
begin
ShowMessage('Korisničko ime ili lozinka nisu validni!');
end;
end;

Can I make a quickly SQL call in the MainThread? Delphi

I have several SQL calls in my Delphi VCL application which uses FireDac to call a MySQL Server to get some data.
However, I am doing all this calls inside the UIThread because they take only a couple of milliseconds. Like the example below:
This is my UI Form
type
TfrmCadPlacas = class(TForm)
lblNumeroDaPlaca: TLabel;
...
...
...
procedure TfrmCadPlacas.btnSalvarClick(Sender: TObject);
begin
// ------------- SQL -------------
if not EstaEditando then
begin
InserirPlaca(Placa, Marca, Modelo, Cor, IDLote, IDHistorico,
dmDados.IDUsuario, dmDados.IDLoteamento);
ShowMessage(SMsgPlacaInseridaSucesso);
end;
end;
InserirPlaca procedure
procedure InserirPlaca(Placa, Marca, Modelo, Cor:string; IDLote, IDHistorico, IDUsuario, IDLoteamento: Integer);
var
qryInserir: TFDQuery;
begin
qryInserir := TFDQuery.Create(nil);
with qryInserir do
begin
Connection := dmDados.FDConnection;
Active := False;
SQL.Clear;
SQL.Add('INSERT INTO ' + T_PLACAS);
SQL.Add('(' + C_PLACA + ', ');
SQL.Add(C_MARCA + ', ');
SQL.Add(C_MODELO + ', ');
SQL.Add(C_COR + ', ');
SQL.Add(C_ID_LOTE + ', ');
SQL.Add(C_ID_HISTORICO + ') ');
SQL.Add('VALUES (:' + C_PLACA + ', ');
SQL.Add(':' + C_MARCA + ', ');
SQL.Add(':' + C_MODELO + ', ');
SQL.Add(':' + C_COR + ', ');
SQL.Add(':' + C_ID_LOTE + ', ');
SQL.Add(':' + C_ID_HISTORICO + ') ');
Params[0].AsString := Placa;
Params[1].AsString := Marca;
Params[2].AsString := Modelo;
Params[3].AsString := Cor;
Params[4].AsInteger := IDLote;
Params[5].AsInteger := PesquisarHistorico(IDLote);
ExecSQL;
end;
end;
As you can see, I am performing a MySQL Server request in the MainThread.
After watching some classes I noticed it is wrong to perform heavy operation in the UIThread as it should be only for GUI. In my case, the operation is pretty fast so it doesn't disturb the UI, if the internet connection is good.
Should I put this MySQL Server request in a background Thread?

Transfer login from SQL2014 to SQL2008R2

I use a stored procedure called sp_help_revlogin to transfer my SQL2014 logins to SQL2008R2.
I usually use it to transfer logins between SQL2008R2 and it works fine but today i have to transfer 2 logins from 2014 to 2008R2 and i receive this error message :
Msg 15021, Level 16, State 2, Line 2 Invalid value given for parameter
PASSWORD. Specify a valid parameter value.
sp_help_revlogin content ==>
USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_help_revlogin] Script Date: 31/08/2016 11:38:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_help_revlogin] #login_name sysname = NULL AS
DECLARE #name sysname
DECLARE #type varchar (1)
DECLARE #hasaccess int
DECLARE #denylogin int
DECLARE #is_disabled int
DECLARE #PWD_varbinary varbinary (256)
DECLARE #PWD_string varchar (514)
DECLARE #SID_varbinary varbinary (85)
DECLARE #SID_string varchar (514)
DECLARE #tmpstr varchar (1024)
DECLARE #is_policy_checked varchar (3)
DECLARE #is_expiration_checked varchar (3)
DECLARE #defaultdb sysname
IF (#login_name IS NULL)
DECLARE login_curs CURSOR FOR
SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa'
ELSE
DECLARE login_curs CURSOR FOR
SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = #login_name
OPEN login_curs
FETCH NEXT FROM login_curs INTO #SID_varbinary, #name, #type, #is_disabled, #defaultdb, #hasaccess, #denylogin
IF (##fetch_status = -1)
BEGIN
PRINT 'No login(s) found.'
CLOSE login_curs
DEALLOCATE login_curs
RETURN -1
END
SET #tmpstr = '/* sp_help_revlogin script '
PRINT #tmpstr
SET #tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + ##SERVERNAME + ' */'
PRINT #tmpstr
PRINT ''
WHILE (##fetch_status <> -1)
BEGIN
IF (##fetch_status <> -2)
BEGIN
PRINT ''
SET #tmpstr = '-- Login: ' + #name
PRINT #tmpstr
IF (#type IN ( 'G', 'U'))
BEGIN -- NT authenticated account/group
SET #tmpstr = 'CREATE LOGIN ' + QUOTENAME( #name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + #defaultdb + ']'
END
ELSE BEGIN -- SQL Server authentication
-- obtain password and sid
SET #PWD_varbinary = CAST( LOGINPROPERTY( #name, 'PasswordHash' ) AS varbinary (256) )
EXEC sp_hexadecimal #PWD_varbinary, #PWD_string OUT
EXEC sp_hexadecimal #SID_varbinary,#SID_string OUT
-- obtain password policy state
SELECT #is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = #name
SELECT #is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = #name
SET #tmpstr = 'CREATE LOGIN ' + QUOTENAME( #name ) + ' WITH PASSWORD = ' + #PWD_string + ' HASHED, SID = ' + #SID_string + ', DEFAULT_DATABASE = [' + #defaultdb + ']'
IF ( #is_policy_checked IS NOT NULL )
BEGIN
SET #tmpstr = #tmpstr + ', CHECK_POLICY = ' + #is_policy_checked
END
IF ( #is_expiration_checked IS NOT NULL )
BEGIN
SET #tmpstr = #tmpstr + ', CHECK_EXPIRATION = ' + #is_expiration_checked
END
END
IF (#denylogin = 1)
BEGIN -- login is denied access
SET #tmpstr = #tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( #name )
END
ELSE IF (#hasaccess = 0)
BEGIN -- login exists but does not have access
SET #tmpstr = #tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( #name )
END
IF (#is_disabled = 1)
BEGIN -- login is disabled
SET #tmpstr = #tmpstr + '; ALTER LOGIN ' + QUOTENAME( #name ) + ' DISABLE'
END
PRINT #tmpstr
END
FETCH NEXT FROM login_curs INTO #SID_varbinary, #name, #type, #is_disabled, #defaultdb, #hasaccess, #denylogin
END
CLOSE login_curs
DEALLOCATE login_curs
RETURN 0
someone can help me please ?
THanks a lot.
Ludo

how to convert MSSQL Stored Procedure to Mysql SP using 'With' Keyword in mysql?

this is my Stored Procedure of MSSQL and I want to be convert this SP to MySQL,but i cant understand what to used instead of 'with' keyword in MySql so any one help me ??? Thanx in Advance!!!!!
ALTER PROCEDURE [dbo].[TPortRateOnKm_SP_List]
#qtype varchar(MAX) = NULL,
#query varchar(MAX)= NULL,
#Sortname varchar(MAX) =NULL,
#sortorder varchar(MAX) =NULL ,
#PageNo int,
#RecordsPerPage int,
#likesearch int
AS
BEGIN
DECLARE #temp INT;
DECLARE #qry varchar(MAX) = '';
DECLARE #qry1 varchar(MAX) = '';
set #temp = (#PageNo - 1) * #RecordsPerPage
If #query is not null and #query <> ''
Begin
Set #qry1= ' Where '+ #query
End
Else
Begin
Set #qry1= ''
End
If #query is not null and #query <> ''
Begin
Set #query= ' Where ('+ #query + ') and (RowNo > ' +
cast(((#PageNo-1) *#RecordsPerPage) as varchar) + ' AND RowNo <= '
+ cast(#PageNo * #RecordsPerPage as varchar)+ ') '
End
Else
Begin
Set #query= ' Where (RowNo > ' + cast(((#PageNo-1) *#RecordsPerPage) as varchar) + ' AND RowNo <= ' + cast(#PageNo * #RecordsPerPage as varchar)+ ') '
End
If #sortorder is not null and #sortorder <> ''
Begin
Set #sortorder= ' Order By '+ #sortorder
End
Else
Begin
Set #sortorder= ' ORDER BY VehicleId'
End
here is 'With' Keyword
set #qry = 'Set dateformat dmy ;WITH CustomTable as
(Select ROW_NUMBER() OVER ( '+ #sortorder+') as RowNo,A.* From
(select Convert(varchar,T.WefDate,103) As WefDate,T.VehicleId as
VehicleId,V.VehicleNo as VehicleNo,T.StartKm,T.EndKm,T.Rate from
TrnRateOnKmRange T left outer join MasterVehicle V on
V.VehicleId=T.VehicleId) A '
Set #qry= #qry + #qry1
Set #qry= #qry + ' )
SELECT CAST(RowNo AS INT) as
RowNo,WefDate,VehicleId,VehicleNo,StartKm,EndKm,Rate
FROM CustomTable'
Set #qry=#qry + #query + #sortorder
EXECUTE (#qry)
END
can any one do this ??

How to split the name string in mysql?

How to split the name string in mysql ?
E.g.:
name
-----
Sachin ramesh tendulkar
Rahul dravid
Split the name like firstname,middlename,lastname:
firstname middlename lastname
--------- ------------ ------------
sachin ramesh tendulkar
rahul dravid
I've separated this answer into two(2) methods. The first method will separate your fullname field into first, middle, and last names. The middle name will show as NULL if there is no middle name.
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(fullname, ' ', 1), ' ', -1) AS first_name,
If( length(fullname) - length(replace(fullname, ' ', ''))>1,
SUBSTRING_INDEX(SUBSTRING_INDEX(fullname, ' ', 2), ' ', -1) ,NULL)
as middle_name,
SUBSTRING_INDEX(SUBSTRING_INDEX(fullname, ' ', 3), ' ', -1) AS last_name
FROM registeredusers
This second method considers the middle name as part of the lastname. We will only select a firstname and lastname column from your fullname field.
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(fullname, ' ', 1), ' ', -1) AS first_name,
TRIM( SUBSTR(fullname, LOCATE(' ', fullname)) ) AS last_name
FROM registeredusers
There's a bunch of cool things you can do with substr, locate, substring_index, etc. Check the manual for some real confusion. http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
There is no string split function in MySQL. so you have to create your own function. This will help you. More details at this link.
Function:
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');
Usage:
SELECT SPLIT_STR(string, delimiter, position)
Example:
SELECT SPLIT_STR('a|bb|ccc|dd', '|', 3) as third;
+-------+
| third |
+-------+
| ccc |
+-------+
Well, nothing I used worked, so I decided creating a real simple split function, hope it helps:
DECLARE inipos INTEGER;
DECLARE endpos INTEGER;
DECLARE maxlen INTEGER;
DECLARE item VARCHAR(100);
DECLARE delim VARCHAR(1);
SET delim = '|';
SET inipos = 1;
SET fullstr = CONCAT(fullstr, delim);
SET maxlen = LENGTH(fullstr);
REPEAT
SET endpos = LOCATE(delim, fullstr, inipos);
SET item = SUBSTR(fullstr, inipos, endpos - inipos);
IF item <> '' AND item IS NOT NULL THEN
USE_THE_ITEM_STRING;
END IF;
SET inipos = endpos + 1;
UNTIL inipos >= maxlen END REPEAT;
You can use bewlo one also:
SELECT SUBSTRING_INDEX(Name, ' ', 1) AS fname,
SUBSTRING_INDEX(SUBSTRING_INDEX(Name,' ', 2), ' ',-1) AS mname,
SUBSTRING_INDEX(Name, ' ', -1) as lname FROM mytable;
Here is the split function I use:
--
-- split function
-- s : string to split
-- del : delimiter
-- i : index requested
--
DROP FUNCTION IF EXISTS SPLIT_STRING;
DELIMITER $
CREATE FUNCTION
SPLIT_STRING ( s VARCHAR(1024) , del CHAR(1) , i INT)
RETURNS VARCHAR(1024)
DETERMINISTIC -- always returns same results for same input parameters
BEGIN
DECLARE n INT ;
-- get max number of items
SET n = LENGTH(s) - LENGTH(REPLACE(s, del, '')) + 1;
IF i > n THEN
RETURN NULL ;
ELSE
RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(s, del, i) , del , -1 ) ;
END IF;
END
$
DELIMITER ;
SET #agg = "G1;G2;G3;G4;" ;
SELECT SPLIT_STRING(#agg,';',1) ;
SELECT SPLIT_STRING(#agg,';',2) ;
SELECT SPLIT_STRING(#agg,';',3) ;
SELECT SPLIT_STRING(#agg,';',4) ;
SELECT SPLIT_STRING(#agg,';',5) ;
SELECT SPLIT_STRING(#agg,';',6) ;
select (case when locate('(', LocationName) = 0
then
horse_name
else
left(LocationName, locate('(', LocationName) - 1)
end) as Country
from tblcountry;
concat(upper(substring(substring_index(NAME, ' ', 1) FROM 1 FOR 1)), lower(substring(substring_index(NAME, ' ', 1) FROM 2 FOR length(substring_index(NAME, ' ', 1))))) AS fname,
CASE
WHEN length(substring_index(substring_index(NAME, ' ', 2), ' ', -1)) > 2 THEN
concat(upper(substring(substring_index(substring_index(NAME, ' ', 2), ' ', -1) FROM 1 FOR 1)), lower(substring(substring_index(substring_index(f.nome, ' ', 2), ' ', -1) FROM 2 FOR length(substring_index(substring_index(f.nome, ' ', 2), ' ', -1)))))
ELSE
CASE
WHEN length(substring_index(substring_index(f.nome, ' ', 3), ' ', -1)) > 2 THEN
concat(upper(substring(substring_index(substring_index(f.nome, ' ', 3), ' ', -1) FROM 1 FOR 1)), lower(substring(substring_index(substring_index(f.nome, ' ', 3), ' ', -1) FROM 2 FOR length(substring_index(substring_index(f.nome, ' ', 3), ' ', -1)))))
END
END
AS mname
To get the rest of the string after the second instance of the space delimiter
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX('Sachin ramesh tendulkar', ' ', 1), ' ', -1) AS first_name,
SUBSTRING_INDEX(SUBSTRING_INDEX('Sachin ramesh tendulkar', ' ', 2), ' ', -1)
AS middle_name,
SUBSTRING('Sachin ramesh tendulkar',LENGTH(SUBSTRING_INDEX('Sachin ramesh tendulkar', ' ', 2))+1) AS last_name
SELECT
p.fullname AS 'Fullname',
SUBSTRING_INDEX(p.fullname, ' ', 1) AS 'Firstname',
SUBSTRING(p.fullname, LOCATE(' ',p.fullname),
(LENGTH(p.fullname) - (LENGTH(SUBSTRING_INDEX(p.fullname, ' ', 1)) + LENGTH(SUBSTRING_INDEX(p.fullname, ' ', -1))))
) AS 'Middlename',
SUBSTRING_INDEX(p.fullname, ' ', -1) AS 'Lastname',
(LENGTH(p.fullname) - LENGTH(REPLACE(p.fullname, ' ', '')) + 1) AS 'Name Qt'
FROM people AS p
LIMIT 100;
Explaining:
Find firstname and lastname are easy, you have just to use SUBSTR_INDEX function
Magic happens in middlename, where was used SUBSTR with Locate to find the first space position and LENGTH of fullname - (LENGTH firstname + LENGTH lastname) to get all the middlename.
Note that LENGTH of firstname and lastname were calculated using SUBSTR_INDEX
You could use the common_schema and use the tokenize function. For more information about this, follow the links. Your code the would end up like:
call tokenize(name, ' ');
However, be aware that a space is not a reliable separator for first and last name. E.g. In Spain it is common to have two last names.
CREATE DEFINER=`root`#`localhost` FUNCTION `getNameInitials`(`fullname` VARCHAR(500), `separator` VARCHAR(1)) RETURNS varchar(70) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE `result` VARCHAR(500) DEFAULT '';
DECLARE `position` TINYINT;
SET `fullname` = TRIM(`fullname`);
SET `position` = LOCATE(`separator`, `fullname`);
IF NOT `position`
THEN RETURN LEFT(`fullname`,1);
END IF;
SET `fullname` = CONCAT(`fullname`,`separator`);
SET `result` = LEFT(`fullname`, 1);
cycle: LOOP
SET `fullname` = SUBSTR(`fullname`, `position` + 1);
SET `position` = LOCATE(`separator`, `fullname`);
IF NOT `position` OR NOT LENGTH(`fullname`)
THEN LEAVE cycle;
END IF;
SET `result` = CONCAT(`result`,LEFT(`fullname`, 1));
-- SET `result` = CONCAT_WS(`separator`, `result`, `buffer`);
END LOOP cycle;
RETURN upper(`result`);
END
1.Execute this function in mysql.
2.this will create a function. Now you can use this function anywhere you want.
SELECT `getNameInitials`('Kaleem Ul Hassan', ' ') AS `NameInitials`;
3. The above getNameInitails first parameter is string you want to filter and second is the spectator character on which you want to separate you string.
4. In above example 'Kaleem Ul Hassan' is name and i want to get initials and my separator is space ' '.
We have stored the value of course Name and chapter name in single column ChapterName.
Value stored like : " JAVA : Polymorphism "
you need to retrieve CourseName : JAVA and ChapterName : Polymorphism
Below is the SQL select query to retrieve .
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(ChapterName, ' ', 1), ' ', -1) AS
CourseName,
REPLACE(TRIM(SUBSTR(ChapterName, LOCATE(':', ChapterName)) ),':','') AS
ChapterName
FROM Courses where `id`=1;
Please let me know if any question on this.
Combined a few answers here to create a SP that returns the parts of the string.
drop procedure if exists SplitStr;
DELIMITER ;;
CREATE PROCEDURE `SplitStr`(IN Str VARCHAR(2000), IN Delim VARCHAR(1))
BEGIN
DECLARE inipos INT;
DECLARE endpos INT;
DECLARE maxlen INT;
DECLARE fullstr VARCHAR(2000);
DECLARE item VARCHAR(2000);
create temporary table if not exists tb_split
(
item varchar(2000)
);
SET inipos = 1;
SET fullstr = CONCAT(Str, delim);
SET maxlen = LENGTH(fullstr);
REPEAT
SET endpos = LOCATE(delim, fullstr, inipos);
SET item = SUBSTR(fullstr, inipos, endpos - inipos);
IF item <> '' AND item IS NOT NULL THEN
insert into tb_split values(item);
END IF;
SET inipos = endpos + 1;
UNTIL inipos >= maxlen END REPEAT;
SELECT * from tb_split;
drop table tb_split;
END;;
DELIMITER ;
To get the rest of the string after the second instance of the space delimiter:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(MsgRest, ' ', 1), ' ', -1) AS EMailID
, SUBSTRING_INDEX(SUBSTRING_INDEX(MsgRest, ' ', 2), ' ', -1) AS DOB
, IF(
LOCATE(' ', `MsgRest`) > 0,
TRIM(SUBSTRING(SUBSTRING(`MsgRest`, LOCATE(' ', `MsgRest`) +1),
LOCATE(' ', SUBSTRING(`MsgRest`, LOCATE(' ', `MsgRest`) +1)) +1)),
NULL
) AS Person
FROM inbox
DELIMITER $$
DROP FUNCTION IF EXISTS `split_name`$$
CREATE FUNCTION split_name (p_fullname TEXT, p_part INTEGER)
RETURNS TEXT
READS SQL DATA
BEGIN
DECLARE v_words INT UNSIGNED;
DECLARE v_name TEXT;
SET p_fullname=RTRIM(LTRIM(p_fullname));
SET v_words=(SELECT SUM(LENGTH(p_fullname) - LENGTH(REPLACE(p_fullname, ' ', ''))+1));
IF v_words=1 THEN
IF p_part=1 THEN
SET v_name=p_fullname;
ELSEIF p_part=2 THEN
SET v_name=NULL;
ELSEIF p_part=3 THEN
SET v_name=NULL;
ELSE
SET v_name=NULL;
END IF;
ELSEIF v_words=2 THEN
IF p_part=1 THEN
SET v_name=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
ELSEIF p_part=2 THEN
SET v_name=SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1);
ELSEIF p_part=3 THEN
SET v_name=NULL;
ELSE
SET v_name=NULL;
END IF;
ELSEIF v_words=3 THEN
IF p_part=1 THEN
SET v_name=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
ELSEIF p_part=2 THEN
SET p_fullname=SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1);
SET v_name=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
ELSEIF p_part=3 THEN
SET p_fullname=REVERSE (SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1));
SET p_fullname=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
SET v_name=REVERSE(p_fullname);
ELSE
SET v_name=NULL;
END IF;
ELSEIF v_words>3 THEN
IF p_part=1 THEN
SET v_name=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
ELSEIF p_part=2 THEN
SET p_fullname=REVERSE(SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1));
SET p_fullname=SUBSTRING(p_fullname, LOCATE(' ', p_fullname,SUBSTRING_INDEX(p_fullname,' ',1)+1) + 1);
SET v_name=REVERSE(p_fullname);
ELSEIF p_part=3 THEN
SET p_fullname=REVERSE (SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1));
SET p_fullname=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
SET v_name=REVERSE(p_fullname);
ELSE
SET v_name=NULL;
END IF;
ELSE
SET v_name=NULL;
END IF;
RETURN v_name;
END;
SELECT split_name('Md. Obaidul Haque Sarker',1) AS first_name,
split_name('Md. Obaidul Haque Sarker',2) AS middle_name,
split_name('Md. Obaidul Haque Sarker',3) AS last_name
First Create Procedure as Below:
CREATE DEFINER=`root`#`%` PROCEDURE `sp_split`(str nvarchar(6500), dilimiter varchar(15), tmp_name varchar(50))
BEGIN
declare end_index int;
declare part nvarchar(6500);
declare remain_len int;
set end_index = INSTR(str, dilimiter);
while(end_index != 0) do
/* Split a part */
set part = SUBSTRING(str, 1, end_index - 1);
/* insert record to temp table */
call `sp_split_insert`(tmp_name, part);
set remain_len = length(str) - end_index;
set str = substring(str, end_index + 1, remain_len);
set end_index = INSTR(str, dilimiter);
end while;
if(length(str) > 0) then
/* insert record to temp table */
call `sp_split_insert`(tmp_name, str);
end if;
END
After that create procedure as below:
CREATE DEFINER=`root`#`%` PROCEDURE `sp_split_insert`(tb_name varchar(255), tb_value nvarchar(6500))
BEGIN
SET #sql = CONCAT('Insert Into ', tb_name,'(item) Values(?)');
PREPARE s1 from #sql;
SET #paramA = tb_value;
EXECUTE s1 USING #paramA;
END
How call test
CREATE DEFINER=`root`#`%` PROCEDURE `test_split`(test_text nvarchar(255))
BEGIN
create temporary table if not exists tb_search
(
item nvarchar(6500)
);
call sp_split(test_split, ',', 'tb_search');
select * from tb_search where length(trim(item)) > 0;
drop table tb_search;
END
call `test_split`('Apple,Banana,Mengo');
Based on previous answers and do some modifications...
note:
p_delimiter has to be VARCHAR(1) couse CHAR(1) if is ' ' (space) gives '' (removes space and returns empty string)
Instead use of LENGTH I prefer CHAR_LENGTH which is safe for multibyte characters like UTF
DROP FUNCTION IF EXISTS FN_SPLIT_STR;
DELIMITER ;;
CREATE FUNCTION FN_SPLIT_STR(
p_input VARCHAR(2000), p_delimiter VARCHAR(1), p_position INT
)
RETURNS VARCHAR(2000)
DETERMINISTIC
BEGIN
DECLARE chunks INT;
SET chunks := CHAR_LENGTH(p_input) - CHAR_LENGTH(REPLACE(p_input, p_delimiter, '')) + 1;
IF p_position > chunks THEN
RETURN NULL;
END IF;
RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(p_input, p_delimiter, p_position), p_delimiter, -1);
END;;
DELIMITER ;
SELECT "SUBSTRING_INDEX(name, ' ', 1) as first_name", "TRIM(REPLACE(name, SUBSTRING_INDEX(name, ' ', 1), '')) as last_name" FROM tbl;