I am getting this error with the SQL below:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Does someone know how I can solve it?
use character
DECLARE #guild_codex varchar(25)
DECLARE #character_name0 varchar(40)
DECLARE #user_no0 varchar (25), #id varchar (25)
DECLARE #user_no varchar (25), #group_id varchar (25), #amount varchar (25)
DECLARE #free_amount varchar(25), #2mx_Leader varchar(3), #2mx_member varchar (3)
SET #2mx_Leader = 700 SET #2mx_member = 500 SET #id = (SELECT id from
[PC-ID].[Cash].[dbo].[user_cash] where free_amount LIKE 0) SET
#user_no = (SELECT user_no from [PC-ID].[Cash].[dbo].[user_cash]
where free_amount LIKE 0) SET #group_id = (SELECT group_id from
[PC-ID].[Cash].[dbo].[user_cash] where free_amount LIKE 0) SET
#amount = (SELECT amount from [PC-ID].[Cash].[dbo].[user_cash]
where free_amount LIKE 0) SET #free_amount = (SELECT free_amount from
[PC-ID].[Cash].[dbo].[user_cash] where free_amount LIKE 0) SET
#guild_codex = (SELECT guild_code from siege_info where siege_tag LIKE'Y')
SET #character_name0 = (SELECT character_name from guild_char_info
where guild_code LIKE #guild_codex and peerage_code LIKE 0) SET
#user_no0 = (SELECT user_no from user_character where character_name
LIKE #character_name0)
use cash
UPDATE user_cash SET
amount=amount+#2mx_Leader WHERE user_no = #user_no0
Multiple issues with your SQL
To assign values for multiple variables, selecting from the same table, with the same where clause, you are making multiple trips to the DB, while it can be done in one single call, like this:
SELECT
#id = id,
#user_no = user_no,
#group_id = group_id,
#amount = amount,
#free_amount = free_amount
FROM [PC-ID].[Cash].[dbo].[user_cash]
WHERE free_amount LIKE 0
You are using LIKE, which could return multiple rows of data, as stated in your error message. Try using = if you can. Alternately, try executing the Select statements responsible for populating your variables to see if more than one row of data is returned.
Raj
Related
I feed multiple variables to a stored procedure using a case statement. Two of the variables are uniqueidentifier that should cause it to return one row always.
However, I am forced to use a top 1 to get it to avoid an error stating my sub select is wrong or it returns hundreds of thousands of rows and acts as if it is ignoring all of the and statements to force it to filter down to one row. Something is causing the case statement not to treat the WHEN statements together as they should always return either yes or no.
ALTER PROCEDURE [dbo].[test_GetUserID_Date]
(#Enterpriseid CHAR(5),
#PracticeID CHAR(4),
#person_id UNIQUEIDENTIFIER,
#pi_encounter_id UNIQUEIDENTIFIER,
#user_id INTEGER,
#encdate VARCHAR(10),
#is_valid CHAR(1) OUTPUT)
AS
BEGIN
SET #is_valid = (SELECT TOP 1
CASE
WHEN pe.enterprise_id = #Enterpriseid
AND pe.practice_id = #PracticeID
AND pe.person_id = #person_id
AND pe.enc_id = #pi_encounter_id
AND pe.created_by = #user_id
AND CONVERT(VARCHAR, GETDATE(), 112) = #encdate
THEN 'Y'
ELSE 'N'
END
FROM patient_encounter pe)
END
The purpose of a CASE expression is to manipulate the value of a particular field within each and every row returned by a query.
If you run this query, what value do you get back?
SELECT COUNT(1)
FROM Patient_Encounter PE
;
Hundreds of thousands, like you said? - at least, that's what I assume. Because your CASE expression doesn't say "Only return the row where all of these parameters match the field values". What your CASE expression (in fact, any CASE expression) actually says is : "For every row returned from Patient_Encounter, if all of these parameters match, give me a 'Y'. Otherwise, give me an 'N'."
If you want to return only the row where those parameters match, the correct way would be to use those parameter checks within the WHERE clause of the query. Your query doesn't even have a WHERE clause, which means you'll be getting every single row in Patient_Encounter.
Try this:
ALTER PROCEDURE [dbo].[test_GetUserID_Date](
#Enterpriseid CHAR(5)
,#PracticeID CHAR(4)
,#person_id UNIQUEIDENTIFIER
,#pi_encounter_id UNIQUEIDENTIFIER
,#user_id INTEGER
,#encdate VARCHAR(10)
,#is_valid CHAR(1) OUTPUT
)
AS
BEGIN
IF EXISTS (
SELECT TOP 1 1
FROM Patient_Encounter PE
WHERE PE.enterprise_id = #Enterpriseid
AND PE.practice_id = #PracticeID
AND PE.person_id = #person_id
AND PE.enc_id = #pi_encounter_id
AND PE.created_by = #user_id
AND CONVERT(VARCHAR, GETDATE(), 112) = #encdate
)
SET #is_valid = 'Y'
ELSE
SET #is_valid = 'N'
END
You wouldn't have to use TOP 1 here, but I do, because I assumed from what you wrote that the presence of 1 row, or 10, or 1,000 means we should get a 'Y'.
You can test this outside of the procedure by just running it as a regular query:
DECLARE
#Enterpriseid CHAR(5)
,#PracticeID CHAR(4)
,#person_id UNIQUEIDENTIFIER
,#pi_encounter_id UNIQUEIDENTIFIER
,#user_id INTEGER
,#encdate VARCHAR(10)
,#is_valid CHAR(1)
;
IF EXISTS (
SELECT TOP 1 1
FROM Patient_Encounter PE
WHERE PE.enterprise_id = #Enterpriseid
AND PE.practice_id = #PracticeID
AND PE.person_id = #person_id
AND PE.enc_id = #pi_encounter_id
AND PE.created_by = #user_id
AND CONVERT(VARCHAR, GETDATE(), 112) = #encdate
)
SET #is_valid = 'Y'
ELSE
SET #is_valid = 'N'
;
SELECT #is_valid
;
Thanks 3BK this answer worked.
You wouldn't have to use TOP 1 here, but I do, because I assumed from what you wrote that the presence of 1 row, or 10, or 1,000 means we should get a 'Y'.
You can test this outside of the procedure by just running it as a regular query:
DECLARE
#Enterpriseid CHAR(5)
,#PracticeID CHAR(4)
,#person_id UNIQUEIDENTIFIER
,#pi_encounter_id UNIQUEIDENTIFIER
,#user_id INTEGER
,#encdate VARCHAR(10)
,#is_valid CHAR(1)
;
IF EXISTS (
SELECT TOP 1 1
FROM Patient_Encounter PE
WHERE PE.enterprise_id = #Enterpriseid
AND PE.practice_id = #PracticeID
AND PE.person_id = #person_id
AND PE.enc_id = #pi_encounter_id
AND PE.created_by = #user_id
AND CONVERT(VARCHAR, GETDATE(), 112) = #encdate
)
SET #is_valid = 'Y'
ELSE
SET #is_valid = 'N'
;
SELECT #is_valid
;
I am trying to create a stored procedure which passes values from select statement of joined tables as parameters to another stored procedure inside to create return credit for returned purchase which are assigned in the WHERE clause of joined tables (#RANO and #returndate). I want to pass many customers (as #Customer) from the joined tables to the stored procedure CreateManCreditHDFromReturn but it picks the first #RANO in the WHERE clause of the joined statement!
How can I pass multiple values (like customers, divisions,...) from all RANOs in the where clause of the joined table?
Note: RANO mean return authorization of returned purchase.
ALTER PROCEDURE [dbo].[CreateEllieAutoCreditHDFromReturn]
AS
BEGIN
DECLARE #ARReason nVarChar(5),
#DocumentDate Datetime,
#ARDocumentType VarChar(5),
#TRANSACTIONID INT,
#TIMELASTMOD DATETIME,
#USERIDLASTMOD nvarchar(5),
#CompanyCode nVarChar(10),
#Customer nVarChar(10),
#Division nVarChar(5),
#Warehouse nVarChar(10),
#Salesman1 nVarChar(10),
#Currency nVarChar(3),
#ReturnNo int,
#RANO int,
#Style nvarchar(15),
SELECT #Pkey = #CompanyCode = rh.companycode,
#Customer = rh.CUSTOMER,
#Division = rh.DIVISION,
#Warehouse = rh.WAREHOUSE,
#Salesman1 = rh.SALESMAN1,
#Currency = rh.CURRENCY,
#ReturnNo = rh.returnno,
#RANO = rh.RANO
FROM
ReturnDetail rd
INNER JOIN
ReturnHeader rh ON rh.RETURNNO = rd.RETURNNO
WHERE
rh.RETURNDATE >= '2020-03-27 00:00:00'
AND rh.RETURNDATE < '2020-03-28 00:00:00'
AND rd.RANO IN (79383, 79820)
AND rd.ARDOCUMENTNOCOMPANY = 0
SET #ARReason = 'RM'
SET #ARDocumentType = 'RCRDT'
SET #DocumentDate = GETDATE()
SET #TRANSACTIONID = 0
SET #TIMELASTMOD = GETDATE()
SET #USERIDLASTMOD = 'WSchan'
SET #ReferenceNo = 0
DECLARE #CurrDocumentNo Int,#CurrDocumentNoCompany Int
EXEC dbo.CreateManCreditHDFromReturn
#CompanyCode,
#ARReason,
#Customer,
#Division,
#Warehouse,
#Salesman1,
#Currency,
#DocumentDate,
#ReferenceNo,
#ARDocumentType,
#CurrDocumentNo OUTPUT,
#CurrDocumentNoCompany OUTPUT,
#TRANSACTIONID,
#TIMELASTMOD,
#USERIDLASTMOD
END
You can't assign multiple values to scalar variables. If you are restricted in that you have no access to modify dbo.CreateManCreditHDFromReturn then you have to use a cursor or loop and iterate through each record in your query. The stored procedure is coded to accept one value at a time for its input parameters.
If you have the ability to modify dbo.CreateManCreditHDFromReturn then you can update it to accept a table variable, JSON, or XML and then inside that stored procedure you can unpack the input and process it accordingly.
If you have to use a cursor, which I'm guessing is going to be the case, it would look something like this:
DECLARE #CompanyCode NVARCHAR(10);
[...and other variables...]
DECLARE RANOCURS CURSOR FOR
SELECT CompanyCode, [...and other fields...]
FROM ReturnDetail rd
INNER JOIN ReturnHeader rh ON rh.RETURNNO = rd.RETURNNO
WHERE rh.RETURNDATE >= '2020-03-27 00:00:00'
AND rh.RETURNDATE< '2020-03-28 00:00:00'
AND rd.RANO IN (79383, 79820)
AND rd.ARDOCUMENTNOCOMPANY = 0;
OPEN RANOCURS;
FETCH NEXT FROM RANOCURS INTO #CompanyCode, [...other variables...]
DECLARE #CurrDocumentNo INT, #CurrDocumentNoCompany INT;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC dbo.CreateManCreditHDFromReturn
#CompanyCode ,
[...other variable parameters...],
#CurrDocumentNo OUTPUT,
#CurrDocumentNoCompany OUTPUT;
[...do something with the return values...]
FETCH NEXT FROM RANOCURS INTO #CompanyCode, ...[other fields]
END;
CLOSE RANOCURS;
DEALLOCATE RANOCURS;
I have a table that I need to calculate some formulas with DATETIME and DECIMAL(10,2) that are in the table, so far I got this:
ALTER PROCEDURE [dbo].[DEPRE]
AS
BEGIN
DECLARE
#FechaReg DATETIME = (SELECT Fec_ActivoDep FROM Dep_Act),
#Fechahoy DATETIME = (SELECT GETDATE()),
#MESES DATETIME,
#Utililidad1 DECIMAL(10,2),
#Utilidad2 DECIMAL(10,2),
#IVA1 DECIMAL(10,2),
#IVA2 DECIMAL(10,2),
#Deprec1 DECIMAL(10,2),
#Deprec2 DECIMAL(10,2),
#Inversion1 DECIMAL(10,2),
#Inversion2 DECIMAL(10,2),
#Total DECIMAL(10,2),
#Contador INT;
SET #Fechahoy = (SELECT GETDATE());
SET #FechaReg = (SELECT Fec_ActivoDep FROM Dep_Act);
SET #MESES = (DATEDIFF(month, #FechaReg, #Fechahoy));
SET #Utililidad1 = (0.08);
SET #IVA1 = (0.16);
SET #Inversion1 = (SELECT Dbl_MontoInv FROM Dep_Act);
SET #Deprec1 = ((SELECT Dbl_MontoInv*(0.10) FROM Dep_Act));
SET #Deprec2 = (SELECT(((#Inversion1) * ((((#Deprec1) / (12)) * ((SELECT CAST (#MESES AS INT))))))));
SET #Utilidad2 = ((#Deprec2) * (#Utililidad1));
SET #Inversion2 = ((#Inversion1) - (#Deprec2));
SET #IVA2 = ((#Utilidad2) * (#IVA1));
SET #Total = ((#Utilidad2) + (#IVA2));
BEGIN
SELECT * FROM Dep_Act;
IF #FechaReg <> #Fechahoy
BEGIN
PRINT 'Setting the param'
UPDATE Dep_Act
SET Int_Meses = ((SELECT CAST (#MESES AS INT)));
UPDATE Dep_Act
SET Dbl_Depreciacion = #Deprec2;
UPDATE Dep_Act
SET Dbl_Inversion = #Inversion2;
UPDATE Dep_Act
SET Dbl_Margen = #Utilidad2;
UPDATE Dep_Act
SET Dbl_Iva = #IVA2;
UPDATE Dep_Act
SET Dbl_TotalDep = #Total;
END
ELSE
BEGIN
PRINT 'All good'
END;
END;
END;
Running this give me this error:
Msg 512, Level 16, State 1, Procedure dbo.DEPRE, Line 4,20, 24, 25 [Batch Start Line 2]
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
And it makes NULL all the columns I was trying to update.
If in the variable #FechaReg have a WHERE like this:
#FechaReg DATETIME = (SELECT Fec_ActivoDep FROM Dep_Act WHERE Int_IdInmovilizado = 3),
It runs only with the stated value and calculates correctly the DATEDIFF and updates all the table with that value, but the other values I tried to calculate are still NULL
If someone can tell me if I'm using the incorrect syntax or is something I'm not declaring, I would appreciate the help, thank you
To correct your error message just do something like this :
Instead of
#Inversion1 = (SELECT Dbl_MontoInv FROM Dep_Act)
do
#Inversion1 = (SELECT TOP 1 Dbl_MontoInv FROM Dep_Act)
I'm not sure it is what you want.
If I understand correctly, you want to update each row of your table.
You should do a big UPDATE and make your computations using CASE WHEN END and subqueries (don't forget the TOP 1)
It is quite difficult to help you without having your table schema and a good understanding of what you wanna do.
I am trying to create a stored procedure for filtering orders. Basically the users have the option of filtering the order by date from and date to. So they can do search via date from, date to or use both if it makes sense?
Anyhow here is my SQL Server stored procedure so far
ALTER PROCEDURE [dbo].[CN_GetOrderItemByCustID]
#CustomerID int,
#OrderItemWRClass varchar(max) = NULL,
#OrderItemSKUName varchar(50) = NULL,
#OrderItemDateFrom Datetime,
#OrderItemDateTo Datetime
AS
BEGIN
SET NOCOUNT ON;
IF DATEDIFF(d, #OrderItemDateFrom, '01/01/1970') = 0
SET #OrderItemDateFrom = null
IF DATEDIFF(d, #OrderItemDateTo, '01/01/1970') = 0
SET #OrderItemDateTo = null
-- Insert statements for procedure here
SELECT
COM_OrderItem.OrderItemID, COM_Order.OrderID,
COM_Order.OrderDate, COM_OrderItem.OrderItemUnitCount,
COM_OrderItem.OrderItemStatus, COM_OrderItem.OrderItemSKUNAME,
COM_OrderItem.OrderItemSKUID
FROM
COM_OrderItem
INNER JOIN
COM_Order ON COM_Order.OrderID = COM_OrderItem.OrderItemOrderID
WHERE
COM_Order.OrderCustomerID = #CustomerID
OR COM_OrderItem.OrderItemWRClass LIKE #OrderItemWRClass + '%'
OR COM_OrderItem.OrderItemSKUName LIKE #OrderItemSKUName + '%'
OR CONVERT(VARCHAR, COM_Order.OrderDate, 120) LIKE #OrderItemDateFrom + '%'
ORDER BY
COM_Order.OrderDate DESC
However I am not sure on how to put the date from (OrderItemDateFrom) and date to (OrderItemDateTo) in the final SQL statement?
Should I be using OR CONVERT(VARCHAR, COM_Order.OrderDate, 120) LIKE #OrderItemDateFrom + '%' -- which gives me an error
Conversion failed when converting date and/or time from character string.
I know in a normal SQL query I would use Between OrderItemDateFrom and OrderItemDateTo
Thanks
Use this logic
ALTER PROCEDURE [dbo].[CN_GetOrderItemByCustID]
-- Add the parameters for the stored procedure here
#CustomerID int,
#OrderItemWRClass varchar(max) = NULL,
#OrderItemSKUName varchar(50) = NULL,
#OrderItemDateFrom Datetime,
#OrderItemDateTo Datetime
AS
BEGIN
SET NOCOUNT ON;
IF DATEDIFF(d,#OrderItemDateFrom,'01/01/1970')=0 SET #OrderItemDateFrom = '01/01/1970';
IF DATEDIFF(d,#OrderItemDateTo,'01/01/1970')=0 SET #OrderItemDateTo = '31/12/2199';
-- Insert statements for procedure here
SELECT COM_OrderItem.OrderItemID, COM_Order.OrderID, COM_Order.OrderDate, COM_OrderItem.OrderItemUnitCount, COM_OrderItem.OrderItemStatus, COM_OrderItem.OrderItemSKUNAME,
COM_OrderItem.OrderItemSKUID
FROM COM_OrderItem
INNER JOIN COM_Order ON COM_Order.OrderID = COM_OrderItem.OrderItemOrderID
WHERE COM_Order.OrderCustomerID = #CustomerID OR COM_OrderItem.OrderItemWRClass LIKE #OrderItemWRClass + '%' OR COM_OrderItem.OrderItemSKUName LIKE #OrderItemSKUName + '%'
OR (COM_OrderDate>=#OrderItemDateFrom && COM_OrderDate<=#OrderItemDateTo )
ORDER BY COM_Order.OrderDate DESC
Try it . It should work.
Your logic can be simplified a little by allowing NULL values for #OrderItemDateFrom and #OrderItemDateTo. Also, if filters values and column values are all DATETIMEs, you should try to compare directly to allow indexes usages (if any applied on the DATETIME column):
ALTER PROCEDURE [dbo].[CN_GetOrderItemByCustID]
#CustomerID int,
#OrderItemWRClass varchar(max) = NULL,
#OrderItemSKUName varchar(50) = NULL,
#OrderItemDateFrom Datetime = NULL, -- TODO: change caller to not provide parameter, or leave it to null
#OrderItemDateTo Datetime = NULL -- TODO: change caller to not provide parameter, or leave it to null
AS
BEGIN
SET NOCOUNT ON;
-- when working with dates try to use an unambiguous format like 'YYYY-MM-DD'
SET #OrderItemDateFrom = ISNULL(#OrderItemDateFrom, '1970-01-01')
-- assign a very large date to act like not provided
-- going one day after to catch DATETIMEs with provided time
SET #OrderItemDateTo = DATEADD(day, 1, ISNULL(#OrderItemDateTo, '3000-01-01'))
-- Insert statements for procedure here
SELECT
COM_OrderItem.OrderItemID, COM_Order.OrderID,
COM_Order.OrderDate, COM_OrderItem.OrderItemUnitCount,
COM_OrderItem.OrderItemStatus, COM_OrderItem.OrderItemSKUNAME,
COM_OrderItem.OrderItemSKUID
FROM COM_OrderItem
INNER JOIN COM_Order ON COM_Order.OrderID = COM_OrderItem.OrderItemOrderID
WHERE COM_Order.OrderCustomerID = #CustomerID
OR COM_OrderItem.OrderItemWRClass LIKE #OrderItemWRClass + '%'
OR COM_OrderItem.OrderItemSKUName LIKE #OrderItemSKUName + '%'
-- between can be used
OR (COM_OrderDate BETWEEN #OrderItemDateFrom AND #OrderItemDateTo)
ORDER BY
COM_Order.OrderDate DESC
END
Another option is to use dynamic SQL and construct it based on parameters values (i.e. insert WHERE condition if filter value is provided). This is particularly useful when filters numbers is relatively low compared to the total number of filters, as ORs are not performance friendly.
NOTE: shouldn't your filters apply in conjuction (i.e. use AND instead of OR)? It would make sense to allow the user to filter by several value in the same time.
ALTER PROCEDURE [dbo].[CN_GetOrderItemByCustID]
#CustomerID int,
#OrderItemWRClass varchar(max) = NULL,
#OrderItemSKUName varchar(50) = NULL,
#OrderItemDateFrom Datetime,
#OrderItemDateTo Datetime
AS
BEGIN
SET NOCOUNT ON;
IF DATEDIFF(d, #OrderItemDateFrom, '01/01/1970') = 0
SET #OrderItemDateFrom = null
IF DATEDIFF(d, #OrderItemDateTo, '01/01/1970') = 0
SET #OrderItemDateTo = null
-- Insert statements for procedure here
SELECT
COM_OrderItem.OrderItemID, COM_Order.OrderID,
COM_Order.OrderDate, COM_OrderItem.OrderItemUnitCount,
COM_OrderItem.OrderItemStatus, COM_OrderItem.OrderItemSKUNAME,
COM_OrderItem.OrderItemSKUID
FROM
COM_OrderItem
INNER JOIN
COM_Order ON COM_Order.OrderID = COM_OrderItem.OrderItemOrderID
WHERE
COM_Order.OrderCustomerID = #CustomerID
OR COM_OrderItem.OrderItemWRClass LIKE #OrderItemWRClass + '%'
OR COM_OrderItem.OrderItemSKUName LIKE #OrderItemSKUName + '%'
OR (#OrderItemDateFrom IS NULL OR COM_Order.OrderDate >=#OrderItemDateFrom)
OR (#OrderItemDateTo IS NULL OR COM_Order.OrderDate <=#OrderItemDateTo)
ORDER BY
COM_Order.OrderDate DESC
You should Try this.
OR (#OrderItemDateFrom IS NULL OR COM_Order.OrderDate >=#OrderItemDateFrom)
OR (#OrderItemDateTo IS NULL OR COM_Order.OrderDate <=#OrderItemDateTo)
Just Edit and try this condition..
I have the stored proc as follows, it always shows the following error whenever I execute it:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Here's the stored proc code:
DECLARE #Wishlist_AutoID VARCHAR(MAX) = (SELECT Wishlist_AutoID FROM ecommerce.ShoppingCartItem WHERE AutoID = #CartItem_AutoID)
DECLARE #Fulfiller_AutoID BIGINT = (SELECT a.Member_AutoID FROM ecommerce.ShoppingCart a INNER JOIN ecommerce.ShoppingCartItem bON a.AutoID = b.ShoppingCart_AutoID)
UPDATE ecommerce.WishList
SET isFulfilled = 1, FulfilledOn = GETDATE(), FulfilledBy = #Fulfiller_AutoID
WHERE AutoID IN (
SELECT data FROM dbo.Split(#Wishlist_AutoID, ';')
)
SET #Result = ##ROWCOUNT
RETURN #Result
One of you first two variable assignments is the problem:
DECLARE #Wishlist_AutoID VARCHAR(MAX) = (SELECT Wishlist_AutoID FROM ecommerce.ShoppingCartItem
WHERE AutoID = #CartItem_AutoID)
OR
DECLARE #Fulfiller_AutoID BIGINT = (SELECT a.Member_AutoID FROM ecommerce.ShoppingCart a
INNER JOIN ecommerce.ShoppingCartItem b
ON a.AutoID = b.ShoppingCart_AutoID)
These queries could return more than one row, and you can't assign multiple rows to a scaler variable.
Given their subsequent usage, I would say it is the second assignment (#Fulfiller_AutoID ).
Most likely, in either of the lines;
DECLARE #Wishlist_AutoID VARCHAR(MAX) = (
SELECT Wishlist_AutoID
FROM ecommerce.ShoppingCartItem
WHERE AutoID = #CartItem_AutoID)
DECLARE #Fulfiller_AutoID BIGINT = (
SELECT a.Member_AutoID FROM ecommerce.ShoppingCart a
INNER JOIN ecommerce.ShoppingCartItem b
ON a.AutoID = b.ShoppingCart_AutoID)
...your query returns more than one row, so the assignment to a single VARCHAR/BIGINT variable is invalid.