Stored Procedure in MSSQL for joining two tables - mysql

I am trying to write a Stored Procedure to authenticate login.
I have two tables which will hold the data table structure given as below.
Table : UserMaster
Userid Password IsActive
1111 xyz 1
2222 abc 0
Table : Userdetailes
Userid Status StartDate EndDate
1111 1 2015-08-01 2015-08-24
2222 0 2015-08-01 2015-08-10
this is how the data is stored in two tables
I want to write a stored procedure to view data from using join

Try something like this.....
CREATE PROCEDURE [dbo].[uspauth]
#LoginId NVARCHAR(30)
,#ActiveStatus INT OUTPUT
AS
BEGIN
SET NOCOUNT ON
BEGIN TRY
--1 - Both Active, 2 - User InActive & Package Active, 3 - User Inactive & Package Inactive , 4 - Not authosrised
DECLARE #Username VARCHAR(40), #isAct Bit,#stat Bit
IF NOT EXISTS(SELECT 1 FROM UserSet where UserID = #LoginId)
BEGIN
RAISERROR('login does not exist',16,1)
RETURN;
END
SELECT #Username = ISNULL(UserID,0), #isAct = ISNULL(IsActive, 0) from UserSet where UserID = #LoginId)
Select #stat = ISNULL([status],0) from Subscription where UserID = #LoginId
and (DateOfStart <= CAST(GETDATE() as DATE) or DateOfStart is NULL)
and (DateOfEnd >= Cast(GETDATE() as DATE) or DateOfEnd is NULL)
IF (#isAct = 1 AND #stat = 1) --1 - Both Active
BEGIN
SET #ActiveStatus = 1;
END
ELSE IF (#isAct = 0 AND #stat = 1) -- 2 - User InActive & Package Active
BEGIN
SET #ActiveStatus = 2;
END
ELSE IF (#isAct = 1 AND #stat = 0) -- 3 - User Active & Package Inactive
BEGIN
SET #ActiveStatus = 3;
END
ELSE IF (#isAct = 0 AND #stat = 0) -- 4 - Not authosrised
BEGIN
SET #ActiveStatus = 4;
END
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
BEGIN
ROLLBACK TRAN
END
EXEC uspProcErrorLog
END CATCH
END

The last if else code block can be simplified with case expression:
set #status = case when #isAct = 1 and #stat = 1 then 1
when #isAct = 0 and #stat = 1 then 2
when #isAct = 1 and #stat = 0 then 3
when #isAct = 0 and #stat = 0 then 4
end
return #status

Related

Executing a stored procedure inside another stored procedure

I am working with a bank database with two tables i.e [Card] and [Transaction].
I have created a stored procedure login that gets as inputs pin and cardNumber and returns the validity of card in an output parameter. Now, I have created another stored procedure withdraw that gets inputs pin, cardNum, transactionAmount and starts a transaction. I am trying to use p1 procedure to handle the validity part. Here are the 2 procedures
create procedure login
#status int output,
#pin varchar(4),
#cnum varchar(20)
as
begin
if exists (select * from [Card] where PIN = #pin AND cardNum = #cnum)
begin
set #status = 1
end
else
begin
set #status = 0
end
end
alter procedure WithDraw
#pin varchar(4),
#cnum varchar(20),
#trAmount int
as
begin
declare #m int
exec login #pin = N'0234', #cnum = N'2324325423336', #status = #m OUTPUT
if (select #m) = 1
--if exists (select * from [Card] where cardNum = #cnum AND pin = #pin)
--working fine with above statement
begin
if exists (select * from [Card]
where cardNum = #cnum AND pin = #pin AND (balance > #trAmount))
begin
update [Card]
set balance = balance - #trAmount
where cardNum = #cnum AND pin = #pin
declare #maxID int
select #maxID = MAX(transId) from [Transaction]
insert into [Transaction]
values (#maxID + 1, GETDATE(), #cnum, #trAmount, 1)
print 'Transaction successful'
end
else
begin
select #maxID = MAX(transId) from [Transaction]
insert into [Transaction]
values(#maxID + 1, GETDATE(), #cnum, #trAmount, 4)
print 'Transaction unsuccessful! Insufficient balance in card'
end
end
else
begin
print 'login failed'
end
end
exec WithDraw #pin = N'1770', #cnum = N'1324327436569', #trAmount = 50000
However, when I execute withdraw with login procedure inside, login always fails. When i execute without login procedure everything works fine. Any help will be greatly appreciated.

generated column with condition sql

mysql command to generate a column from other column according to condition
loan_amount | installment | start_date | status
------------------------------------------------------------------
500 | 100 | 2018-1-1 |
if (loan_amount % installment != 0) then month_required to pay = loan_amount / installment + 1
else month_required = loan_amount / installment;
then i want to check by adding month_required to start_date if it has crossed current date. If not then status would generate "incomplete" else "complete" .
delimiter //
set #month = "0";
create trigger `status_check` before insert on `loan`
for each row
begin
if NEW.loan_amount% NEW.installment != 0
then set #month NEW.loan_amount/ NEW.installment +1;
else set #month = NEW.loan_amount/NEW.installment;
end if ;
if NOW() <= dateadd(NEW.start_date,INTERVAL #month MONTH)
then set NEW.status = "incomplete";
else set NEW.status = "complete";
end if;
end;
//
DELIMITER ;
what is the error here? please help.
I Can't make the real answer as you don't provide all your database field nor a data sample, but some BEFORE INSERT and BEFORE UPDATE Trigger will probably do the job.
This is the base for the BEFORE INSERT :
DELIMITER //
DROP TRIGGER IF EXISTS `trg_test_insert`;
//
CREATE TRIGGER `trg_test_insert`
BEFORE INSERT ON `table`
FOR EACH ROW
BEGIN
IF NEW.loan_amount % NEW.installment != 0 THEN
SET NEW.month_required = NEW.loan_amount / NEW.installment + 1;
ELSE
SET NEW.month_required = NEW.loan_amount / NEW.installment;
END IF;
END;
//
DELIMITER ;
Take a look at MySQL 5.7 Reference Manual / ... / Trigger Syntax and Examples
And at :
MYSQL Triggers - how to store the result of a calculated field

Select all child records against specific id in mysql

I have many records in task table with parent_id.
Like
task_id name parent
1 a 0
2 b 1
3 c 2
4 d 3
5 e 0
6 f 5
I have task_id 1 in my shared table so I want to select it and its all child record till nth level.
I have this query
SELECT
shared.task_id,tsk.*
FROM
tbl_sharedtasks shared, tbl_tasks tsk
WHERE
shared.user_id=1 AND tsk.task_id=shared.task_id.shared
suppose 1
But this select only one record. Problem is that this should select First and task_id 1 have a child record task_id 2 and 2 have 3 parent and 3 have 4 parent. so these all should select all which have relation with parent
MySQL doesn't support selecting recursively, but you can do it in your app code with more queries, however, this may cause performance issue if your task table goes large. Consider change your design.
This is done through create function first in Mysql as below
DROP FUNCTION `taskLevel`//
CREATE DEFINER=`root`#`localhost` FUNCTION `taskLevel`(GivenID int(11)) RETURNS varchar(1024) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE lvl varchar(10);
DECLARE rv,q,queue,queue_children,front_id VARCHAR(1024);
DECLARE queue_length,pos INT;
SET rv = '';
SET queue = GivenID;
SET queue_length = 1;
WHILE queue_length > 0 DO
SET front_id = queue;
IF queue_length = 1 THEN
SET queue = '';
ELSE
SET pos = LOCATE(',',queue) + 1;
SET q = SUBSTR(queue,pos);
SET queue = q;
END IF;
SET queue_length = queue_length - 1;
SELECT IFNULL(qc,'') INTO queue_children
FROM (SELECT GROUP_CONCAT(task_id) qc
FROM tbl_tasks WHERE parent_id = front_id) A;
IF LENGTH(queue_children) = 0 THEN
IF LENGTH(queue) = 0 THEN
SET queue_length = 0;
END IF;
ELSE
IF LENGTH(rv) = 0 THEN
SET rv = queue_children;
ELSE
SET rv = CONCAT(rv,',',queue_children);
END IF;
IF LENGTH(queue) = 0 THEN
SET queue = queue_children;
ELSE
SET queue = CONCAT(queue,',',queue_children);
END IF;
SET queue_length = LENGTH(queue) - LENGTH(REPLACE(queue,',','')) + 1;
END IF;
END WHILE;
RETURN rv;
END
SELECT `task_id` , `title` , taskLevel(`task_id`) AS children FROM tbl_tasks WHERE `task_id` =1

SQL: extract items from list to put onto new row

Is there a way to extract out list items within a column and put each item in its own row? I also want to do away with the list brackets [] too! Can anyone help?
Input:
name doc_id type
JD [409839589143224] 1843
JD [470573363064028,239564999464566] 778
BK [426580780775177,342730259144025] 202
Desired Output:
name doc_id type
JD 409839589143224 1843
JD 470573363064028 778
JD 239564999464566 778
BK 426580780775177 202
BK 342730259144025 202
this is solution using tsql, i`m sure you can do the same with MySql
CREATE FUNCTION ufn_split (#list nvarchar(MAX))
RETURNS #tbl TABLE (part nvarchar(max) NOT NULL) AS
BEGIN
DECLARE #pos int,
#nextpos int,
#valuelen int
SELECT #pos = 0, #nextpos = 1
WHILE #nextpos > 0
BEGIN
SELECT #nextpos = charindex(',', #list, #pos + 1)
SELECT #valuelen = CASE WHEN #nextpos > 0
THEN #nextpos
ELSE len(#list) + 1
END - #pos - 1
INSERT #tbl (part)
VALUES (substring(#list, #pos + 1, #valuelen))
SELECT #pos = #nextpos
END
RETURN
END;
GO
SELECT t.name, st.part, t.type
FROM #table AS t
CROSS APPLY ufn_split( LEFT(RIGHT(t.doc_id, LEN(t.doc_id) - 1),LEN(t.doc_id) - 2) ) AS st;
The first function is implimentation of Split function on TSQL from here Split function equivalent in T-SQL?

mysql stored procedure error (1172, 'Result consisted of more than one row')

When trying to run the following stored procedure from django, I get an OperationError (1172, 'Result consisted of more than one row') Any idea what I might be doing wrong?
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `UpdatePrices`(IN storeId int, IN bottleSize VARCHAR(50))
BEGIN
DECLARE amount DECIMAL(10,2); DECLARE isCustom INT DEFAULT 0;
DECLARE changeType VARCHAR(50) DEFAULT 'State'; DECLARE updateType INT DEFAULT 0;
IF bottleSize = '1000 Ml' THEN
SELECT S1000IncreaseChoices INTO changeType FROM store_store WHERE StoreID = storeId;
IF changeType = 'State' THEN
SELECT updateType = 0;
END IF;
IF changeType = 'Flat' THEN
SELECT S1000IncreaseAmount INTO amount FROM store_store WHERE StoreID = storeId;
SELECT updateType = 1;
END IF;
IF changeType = 'Percent' THEN
SELECT 1 - S1000IncreaseAmount/100 INTO amount FROM store_store WHERE StoreID = storeId;
SELECT updateType = 2;
END IF;
END IF;
IF updateType = 0 THEN
update store_storeliquor SL
inner join liquor_liquor LL
on liquorID_id = id
set StorePrice = ShelfPrice
where BottleSize = bottleSize
and storeID_id = storeId
and custom = 0;
END IF;
IF updateType = 1 THEN
update store_storeliquor SL
inner join liquor_liquor LL
on liquorID_id = id
set StorePrice = OffPremisePrice + amount
where BottleSize = bottleSize
and storeID_id = storeId
and custom = 0;
END IF;
IF updateType = 1 THEN
update store_storeliquor SL
inner join liquor_liquor LL
on liquorID_id = id
set StorePrice = OffPremisePrice / amount
where BottleSize = bottleSize
and storeID_id = storeId
and custom = 0;
END IF;
END
I'm not sure if it matters, but I initiate the stored procedure like so:
def priceupdate(request, store_id):
cursor = connection.cursor()
cursor.callproc("UpdatePrices", (store_id, '1000 ML'))
cursor.close()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
Your SELECT...INTO queries give result sets with more then one record. The WHERE filters are incorrect - they compare two the same values StoreID = storeId. Rename IN storeId int parementer to another name. For example - IN storeId_param int
The query will be like this -
SELECT S1000IncreaseChoices INTO changeType FROM store_store WHERE StoreID = storeId_param;
This is a Bug and you need to apply something like that:
SELECT id,data INTO x,y FROM test.t1 LIMIT 1;