Join two table and then search for the match - mysql

I have two table named security_questions and login. Columns in login tables are:
Username, Security_QA_ID, Security_Answer, Security_Attempts,Last_Login,Password_Attempts
where security_questions have:
ID, Name
where Security_QA_ID is referenced with ID
CREATE DEFINER=`satish`#`%` PROCEDURE `p_chkAnswer`(
IN sq VARCHAR(75),
IN sa VARCHAR(20) ,
IN uname VARCHAR(15) ,
out msg INT
)
BEGIN
select (COUNT(*) > 0) INTO #result from login join security_questions on Security_QA_ID = ID where User_Name=uname and Name=sq and Security_Answer=sa;
set msg = #result;
if #result = 1 Then
UPDATE login SET Last_Login=now(),Password_Attempts=0 where User_Name=uname;
else
UPDATE login SET Security_Attempts=Security_Attempts+1 where User_Name=uname;
End if;
END
but in every time only else part get executes. thanks in advance

Your code is quite confusing and hard to read (for me at least), I simplified your statement into a single SELECT so that I can check if your select is correct, and it appears to be correct:
CREATE TABLE `login`
( User_Name text,
Security_QA_ID int(11),
Security_Answer text,
Security_Attempts datetime,
Last_Login datetime,
Password_Attempts int(11)
);
CREATE TABLE `security_questions`
(ID int(11),
Name text
);
INSERT INTO login SET
User_name = 'a',
Security_QA_ID = 1,
Security_Answer = 'c',
Security_Attempts = NOW(),
Last_Login = NOW(),
Password_Attempts = 0;
INSERT INTO security_questions SET
ID = 1,
Name = 'b';
And the select
SELECT IF(COUNT(*) > 0, 1, 0) AS Authenticated
from (login)
LEFT join security_questions on Security_QA_ID = ID
where User_Name='a' and Name='b' and Security_Answer='c'
Do you have to use this DEFINER? wouldn't it be easier to write PHP/Perl/etc code to check for Authenticated as being non-zero?

Related

MySQL update if exists else insert throws syntax error

Trying to update existing records based not on ID but specific usernames with no luck. I wrote the following query but I got a syntax error I can't find.
IF EXISTS (SELECT 1 FROM users WHERE username = 'REMOTEUSER1')
THEN
BEGIN
UPDATE users
SET username = 'REMOTEUSER1', password = 'BJxp98YkVbt4', exp_date = '1650991560', member_id = 1, is_mag = '0', play_token = '', reseller_notes = ''
WHERE username = 'REMOTEUSER1'
END;
ELSE
BEGIN
INSERT INTO users (
username,
password,
exp_date,
member_id,
is_new,
play_token,
reseller_notes
) VALUES (
'REMOTEUSER1',
'BJxp98YkVbt4',
'1650991560',
1,
0,
'',
''
)
END;
END IF;
The IF-ELSE conditional statement construct is supported to be used through FUNCTIONS or STORED PROCEDURES that can't use it like a normal query.
If your username column is UNIQUE index or PRIMARY KEY I would use INSERT ... ON DUPLICATE KEY UPDATE Statemen
INSERT INTO users (
username,
password,
exp_date,
member_id,
is_new,
play_token,
reseller_notes
) VALUES (
'REMOTEUSER1',
'BJxp98YkVbt4',
'1650991560',
1,
0,
'',
''
) ON DUPLICATE KEY UPDATE
password = 'BJxp98YkVbt4',
exp_date = '1650991560',
member_id = 1,
is_mag = '0',
play_token = '',
reseller_notes = '';
sqlfiddle
If is_mag is a bit(1) (boolean), then it's likely the update portion where you set it to '0'
either set the boolean to an integer value of 0, or prefix it with b
i.e.
my_bool = b'0'

How stored procedure output instead of rows count?

My stored procedure always returns 0. I tried unique data and duplicated but the insert is done with success but the return value is always the same #new_identity = 0
CREATE PROCEDURE [dbo].[spAddAuthor]
#Author tyAuthor READONLY,
#new_identity INT = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
-- check if the author exists
IF NOT EXISTS (SELECT Id_Author FROM dbo.Authors
WHERE (dbo.Authors.Username = (SELECT Username FROM #Author)
OR dbo.Authors.phone = (SELECT phone FROM #Author)
OR dbo.Authors.email = (SELECT email FROM #Author)))
BEGIN
INSERT INTO dbo.Authors (Username, sexe, email, phone, address)
SELECT [Username], [sexe], [email], [phone], [address]
FROM #Author
-- output the new row
SELECT #new_identity = ##IDENTITY;
END
ELSE
BEGIN
-- get the author Id if already exists
SELECT #new_identity = (SELECT TOP 1 Id_Author
FROM dbo.Authors
WHERE (dbo.Authors.Username = (SELECT Username FROM #Author)
OR dbo.Authors.phone = (SELECT phone FROM #Author)
OR dbo.Authors.email = (SELECT email FROM #Author)))
END
END
I found that in the declaration of the parameters I put null beside the output and that what caused the problem.
#new_identity INT = NULL OUTPUT
but I don't understand why, I thought the 'null' was like the default value, or when you try to make the parameter optional you add null as default value.
can someone explain, please?

Procedure that store updated history of table in another table

I have two tables Person with PersonId, Name,Address,Mobile and PersonLog with Id,Name,Address,Mobile,FK_PersonId. I am trying store the old data in PersonLog and Person to be updated.
This is my procedure, but it is only updating Person and not storing selected(edited) data from Person into PersonLog :
CREATE PROCEDURE [dbo].[UpdateInsertPerson]
(
#PersonId int,
#PersonName nvarchar(40),
#Address nvarchar(60),
#Mobile nvarchar(15)
)
AS
BEGIN
INSERT INTO
dbo.PersonLog(PersonName, Address, Mobile, FK_PersonId)
SELECT
Person.PersonId, Person.PersonName, Person.Address, Person.Mobile
FROM
dbo.Person JOIN dbo.PersonLog ON PersonLog.FK_PersonId = Person.PersonId;
UPDATE
dbo.Person
SET
PersonName = #PersonName,
Address = #Address,
Mobile = #Mobile
WHERE
PersonId = #PersonID;
END
Any help?
I might suggest these changes... but I don't know what you're after exactly. Or your data.
I highly suggest adding a modified date to your PersonLog table....
alter table PersonLog add Modified_DT datetime default getdate()
this code works for me...
CREATE PROCEDURE UpdateInsertPerson (
#PersonId int,
#PersonName nvarchar(40) = null,
#Address nvarchar(60) = null,
#Mobile nvarchar(15) = null
)
AS
BEGIN
INSERT INTO PersonLog (FK_PersonId, PersonName, Address, Mobile)
SELECT Person.PersonID,
Person.PersonName,
Person.Address,
Person.Mobile
FROM Person
WHERE Person.PersonId=#PersonID;
UPDATE Person
SET PersonName = case when #PersonName is not null then #PersonName else PersonName end,
Address = case when #Address is not null then #Address else Address end,
Mobile = case when #Mobile is not null then #Mobile else Mobile end
WHERE PersonId = #PersonID;
END
insert into Person values (1,'kim','123 main st','555-555-5555');
exec UpdateInsertPerson 1,'kim';
exec UpdateInsertPerson 1,'ryan';
exec UpdateInsertPerson 1,'taco';
select * from personlog
select * from Person
that way will not insert a brand new person. this way will... for this to work, your Person.PersonID must be set like this: PersonID int IDENTITY(1,1) primary key.
ALTER PROCEDURE UpdateInsertPerson (
#PersonId int = null,
#PersonName nvarchar(40) = null,
#Address nvarchar(60) = null,
#Mobile nvarchar(15) = null
)
AS
BEGIN
INSERT INTO PersonLog (FK_PersonId, PersonName, Address, Mobile)
SELECT Person.PersonID,
Person.PersonName,
Person.Address,
Person.Mobile
FROM Person
WHERE Person.PersonId=#PersonID;
UPDATE Person
SET PersonName = case when #PersonName is not null then #PersonName else PersonName end,
Address = case when #Address is not null then #Address else Address end,
Mobile = case when #Mobile is not null then #Mobile else Mobile end
WHERE PersonId = #PersonID;
-- this inserts into Person if they didn't already exist
IF ##ROWCOUNT = 0
BEGIN
INSERT Person (PersonName, Address, Mobile) VALUES (#PersonName, #Address, #Mobile);
END
END
The procedure is not working as you are joining PersonLog with Person table in the select statement. As initially this table is empty the condition PersonLog.FK_PersonId = Person.PersonId is false and nothing gets inserted (as FK_PersonId is NULL)
I don't see any purpose of joining the 2 tables to insert the record in Log table. just remove the join condition and include a where clause as Person.PersonId=#PersonID

Incorrect query result

I have a query which is not returning correct result:
SELECT t.GroupName AS GroupName, t.ApplicationName AS ApplicationName, t.UserName
FROM UserApplication t
WHERE (#ApplicationName IS NULL OR #ApplicationName = '' OR t.ApplicationName = #ApplicationName) AND
(#UserName IS NULL OR #UserName = '' OR t.UserName= #UserName );
Table structure:
CREATE TABLE userapplication
(`ID` INT,
`ApplicationName` VARCHAR(100),
`GroupName` VARCHAR(100),
`UserName` VARCHAR(100))
When I do not pass any value to the parameter then it showing all rows from the table while if pass any value to the parameter #ApplicationName or #UserName it is giving me same result.
Please help
If you correctly set values of user variables your query will work just fine
SET #ApplicationName = 'App 1';
SET #UserName = '';
SELECT t.GroupName,
t.ApplicationName,
t.UserName
FROM UserApplication t
WHERE (COALESCE(#ApplicationName, '') = ''
OR t.ApplicationName = #ApplicationName)
AND (COALESCE(#UserName, '') = ''
OR t.UserName= #UserName);
It's a little bit more succinct version of your query
Here is SQLFiddle demo

Need help in converting INSERT\UPDATE to MERGE

Is this a good candidate for a MERGE command?
Must the source data also be another table or can it be variables that are passed?
If it must be a table, is inserting the passed variables into a temp table sane?
Could you help me with the syntax?
CREATE PROCEDURE [dbo].[usp_ConvertToMerge]
#GL_DT date
,#SRC_SYS_ID varchar(60)
,#MLR_SRC_SYS_CD char(3)
,#TRSRY_FEED_DT date
,#Data varchar(20)
AS
BEGIN
IF NOT EXISTS (SELECT
#GL_DT
FROM
MLR_REBATE_IBOR_INFO_2
WHERE
[GL_DT] = #GL_DT
AND [SRC_SYS_ID] = #SRC_SYS_ID
AND [MLR_SRC_SYS_CD] = #MLR_SRC_SYS_CD
AND [TRSRY_FEED_DT] = #TRSRY_FEED_DT)
BEGIN
INSERT INTO [dbo].[MLR_REBATE_IBOR_INFO_2]
([GL_DT],
[SRC_SYS_ID],
[MLR_SRC_SYS_CD],
[TRSRY_FEED_DT],
[Data])
SELECT
#GL_DT
,#SRC_SYS_ID
,#MLR_SRC_SYS_CD
,#TRSRY_FEED_DT
,#Data
END
ELSE
BEGIN
UPDATE [dbo].[MLR_REBATE_IBOR_INFO_2]
SET [Data] = #Data
WHERE [GL_DT] = #GL_DT
AND [SRC_SYS_ID] = #SRC_SYS_ID
AND [MLR_SRC_SYS_CD] = #MLR_SRC_SYS_CD
AND [TRSRY_FEED_DT] = #TRSRY_FEED_DT
END
END
GO
I think I did it:
CREATE PROCEDURE MyMergeTest
#GL_DT date
,#SRC_SYS_ID char(20)
,#MLR_SRC_SYS_CD char(3)
,#TRSRY_FEED_DT date
,#Data varchar(20)
AS
BEGIN
MERGE MLR_REBATE_IBOR_INFO_2 AS target
USING
(
SELECT
#GL_DT
,#SRC_SYS_ID
,#MLR_SRC_SYS_CD
,#TRSRY_FEED_DT
,#Data
) AS source
(
GL_DT
,SRC_SYS_ID
,MLR_SRC_SYS_CD
,TRSRY_FEED_DT
,Data
)
ON (
target.GL_DT = source.GL_DT AND
target.SRC_SYS_ID = source.SRC_SYS_ID AND
target.MLR_SRC_SYS_CD = source.MLR_SRC_SYS_CD AND
target.TRSRY_FEED_DT = source.TRSRY_FEED_DT
)
WHEN MATCHED THEN
UPDATE SET Data = source.Data
WHEN NOT MATCHED THEN
INSERT
(
[GL_DT],
[SRC_SYS_ID],
[MLR_SRC_SYS_CD],
[TRSRY_FEED_DT],
[Data]
)
VALUES
(
[GL_DT], --<<it looks like these can eiether be the variable eg, #GL_DT, or prefixed by 'source.'
[SRC_SYS_ID],
[MLR_SRC_SYS_CD],
[TRSRY_FEED_DT],
[Data]
);
END