I am working with public database Wide World Importers and I try to make some query.For input in this query I want to use scalar variables. You can see code below:
DECLARE #SupplierID int = 7
DECLARE #YearMonth NVARCHAR = '2013.1'
SELECT
pur.SupplierID, SUM(purst.TransactionAmount) AS TotalTransaction,
CONCAT(YEAR(pur.OrderDate), '.', MONTH(pur.OrderDate)) AS YearMonth
FROM
[Purchasing].[PurchaseOrders] AS pur
INNER JOIN
[Purchasing].[SupplierTransactions] AS purst ON purst.SupplierID = pur.SupplierID
WHERE
pur.SupplierID = #SupplierID
AND YearMonth = #YearMonth
GROUP BY
pur.OrderDate, pur.SupplierID
Above code work well and give me good result (but without scalar variable #YearMonth). You can see result below:
But when I try to include YearMonth like scalar variable into this query I get this error:
Msg 207, Level 16, State 1, Line 3831
Invalid column name 'YearMonth'
So can anybody help me how to fix this problem and make query properly?
You can't reference a column declared in the SELECT in the WHERE. You need to reference the actual columns in the table in the WHERE, or use a subquery or CTE.
What you should be doing here, however, is using proper date logic:
DECLARE #SupplierID int = 7,
#StartDate date = '20130101',
#EndDate date = '20130201';
SELECT PO.SupplierID,
SUM(ST.TransactionAmount) AS TotalTransaction,
CONCAT(YEAR(PO.OrderDate), '.', MONTH(PO.OrderDate)) AS YearMonth
FROM [Purchasing].[PurchaseOrders] PO
INNER JOIN [Purchasing].[SupplierTransactions] ST ON ST.SupplierID = PO.SupplierID
WHERE PO.SupplierID = #SupplierID
AND PO.OrderDate >= #StartDate
AND PO.OrderDate < #EndDate
GROUP BY PO.OrderDate,
PO.SupplierID;
I also change your aliases to something a bit more appropriate.
Related
I'd like to update fields while referring to a dynamic column.
The goal is to automate a process because each month the column to refer to changes.
For example it's like having different columns like month1, month2, month3 until month24. Each month, only 1 column needs to be updated but it's a running number that is calculated in another table.
So my question is how to make the query dynamic so that every month i only update the column number that i want and not the other one.
I tried the script below but the following issue comes up
Error converting data type varchar to float.
DECLARE #PromoMonthNumber VARCHAR(60)
DECLARE #PromoMonth VARCHAR(600)
SET #PromoMonthNumber = (SELECT CurrentDemandIndex FROM RidgeSys) --This refer to a number that change all the time
SET #PromoMonth = 'SELECT ABC.PromotionHistory' + #PromoMonthNumber
UPDATE ABC
SET #PromoMonth = table2.promotionhistory
FROM ABC
INNER JOIN (
SELECT Article.code as code, sum(ROUND(#PromoMonth,0)) as promotionhistory
FROM Article
INNER JOIN ABC ON DEF.articlecode = ABC.Articlecode
) as table2
ON ABC.articlecode = table2.code)
Here is your issue:
SELECT Article.code as code, sum(ROUND(#PromoMonth,0)) as promotionhistory
Since #PromoMonth is defined as VARCHAR, if the value is non-numeric, it will fail. Here is an example:
This works fine:
declare #x varchar(100) = '1';
select sum(round(#x,0));
Result:
1
This fails with same error above:
declare #x varchar(100) = 'x';
select sum(round(#x,0));
Result:
Msg 8114, Level 16, State 5, Line 3
Error converting data type varchar to float.
You need to check that the value is numeric before you do the calculation.
The back story is I am trying to write a view that takes a table who's every row is an ID and serialized data for that ID in a clob and presents it in sql navigable form. basically my code looks like:
CREATE VIEW UNSERIALIZED_TABLE_VIEW AS
SELECT
SOURCE_TABLE.ID SOURCE_ID,
a.*
FROM
SOURCE_TABLE,
FUNCTION_WHICH_UNSERIALIZES((SELECT DATA FROM SOURCE_TABLE WHERE ID = SOURCE_ID)
I tried putting the function in the select statement, but that just gave a syntax error about it being undefined. When it runs the error is usually about a subquery returning too many values. I could just unserialize the data in batches, but now I'm really curious what's going wrong.
Example Data
#0History:23:ALPHANUMERICSTUFF1234567ID:11:ACCT1234567SourceMode:6:ANNUAL.ModeChanges:UniqueIndex:23:ALPHANUMERICSTUFF1234567ID:11:ACCT1234567OldValue:1:+NewValue:6:ANNUALChangeType:1:AChangeDate:20:6/03/2013 2:49:32 AM.
#0History:UniqueIndex:95:NOTTHESAME0987654|ALPHANUMERIC534|PRETEND349235|95CHARACTERSID:47:GNR44718500|PNR48CDQ704|PGP48090798|FGDS2345236SourceMode:26:ANNUAL|C-P-D|ANNUAL|ANNUALLoan:3:|||ModeChanges:UniqueIndex:95:00487SOMETHING4264500ORD|992581PROBABLY04ORD|0048SHOULD238BET|0095CHARS436PR638FGP07VDCID:47:GNR44718500|PNR48CDQ704|PGP48090798|FGDS2345236OldValue:7:+|+|+|+NewValue:26:ANNUAL|C-P-D|ANNUAL|ANNUALChangeType:7:A|A|A|AChangeDate:91:12/22/2013 11:53:11 PM|4/22/2013 11:53:11 PM|12/22/2013 11:53:11 PM|12/22/2013 11:53:11 PM.
The data is serialized table data of the form COLUMN_NAME:LENGTH_OF_ENTRY:DATA_FOR_COLUMN_ROW_1|DATA_FOR_COLUMN_ROW2|....NEXT_COLUMN_NAME...
Example of Function:
CREATE FUNCTION FUNCTION_THAT_UNSERIALIZES (#clob varchar(max),#colname varchar(max)) RETURNS #NewValue TABLE (ID INT,value varchar(max)) AS
BEGIN
DECLARE #colstart INT,#lenstart INT,#lenend INT,#collen VARCHAR(MAX),#lngth INT,#tmp VARCHAR(MAX), #rowid INT,#value VARCHAR(max),#next INT;
SELECT
#colstart = CHARINDEX(#colname,#tmp)+1,
#lenstart = CHARINDEX(':',#tmp,#colstart)+1,
#lenend = CHARINDEX(':',#tmp,#lenstart),
#collen = SUBSTRING(#tmp,#lenstart,#lenend - #lenstart),
#lngth = CAST (#collen AS INT),
#tmp = SUBSTRING(#tmp,#lenend,#lngth);
WHILE LEN(#tmp) > 0 BEGIN
SET #next = CHARINDEX('|',#tmp);
IF #next > 0 BEGIN
SET #value = SUBSTRING(#tmp,0,#next);
SET #tmp = SUBSTRING(#tmp,#next+1,LEN(#tmp) - #next);
END ELSE BEGIN
SET #value = #tmp;
SET #tmp = '';
END
INSERT INTO #NewValue VALUES(#rowid,#value)
SET #rowid = #rowid+1;
END
RETURN
Example Error
Msg 512, Level 16, State 1, Line 7
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Msg 4104, Level 16, State 1, Line 15
The multi-part identifier "SOURCE_TABLE.SOURCE_ID" could not be bound.
.. I think there might have been another one, but can't figure out how to reproduce it right this minute.
I think this might be the syntax you need to accomplish what I think you are trying to do.
CREATE VIEW UNSERIALIZED_TABLE_VIEW AS
SELECT
SOURCE_TABLE.ID SOURCE_ID,
a.*
FROM SOURCE_TABLE
CROSS APPLY FUNCTION_WHICH_UNSERIALIZES(DATA, #colname) a
I'm not certain what your #colname parameter should be; it is left out of your code in the question.
I have this error, and I can't fix it
Msg 260, Level 16, State 3, Procedure SP_SAV_ESTADISTICALLAMADAXOPERADOR, Line 7
Disallowed implicit conversion from data type datetime to data type float, table 'APEX.SAV_LLAMADAS', column 'FECHA'. Use the CONVERT function to run this query.
this's my code
CREATE PROCEDURE APEX.SP_SAV_ESTADISTICALLAMADAXOPERADOR
#pCodOperador VARCHAR (20)
AS
BEGIN
SET NOCOUNT ON
SELECT TP.DESCRIPCION AS TIPOLOGIA,
ST.DESCRIPCION AS SUB_TIPOLOGIA,
COUNT(*) AS TOTAL
FROM APEX.SAV_LLAMADAS_DET DT INNER JOIN APEX.SAV_LLAMADAS LL
ON LL.ID_LLAMADA = DT.ID_LLAMADA INNER JOIN APEX.SAV_SUB_TIPOLOGIAS ST
ON DT.COD_TIPOLOGIA = DT.COD_TIPOLOGIA
AND DT.COD_SUBTIPOLOGIA = ST.COD_SUB_TIPOLOGIA INNER JOIN APEX.SAV_TIPOLOGIAS TP
ON TP.COD_TIPOLOGIA = ST.COD_TIPOLOGIA
WHERE DT.USUARIO_CREA = #pCodOperador
AND FLOOR(LL.FECHA) = FLOOR((GETDATE()))
GROUP BY TP.DESCRIPCION, ST.DESCRIPCION
SET NOCOUNT OFF
END
You can't do FLOOR on a datetime datatype. Assuming you are trying to exclude the time portion of a datetime you can do something like this instead.
AND CAST(LL.FECHA AS DATE) = CAST(GETDATE() AS DATE)
My database trigger takes a date from a column and adds 60 days to it and stores it into another column.
And it does as expected when I execute the code in query window and it throws the following error.
Msg 512, Level 16, State 1, Line 4
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
My code:
DECLARE #NextDate date
SELECT #NextDate = (SELECT DATEADD(day, 10, Today) FROM Test)
INSERT INTO Test (Notes, Today)
VALUES ('Testing in Query2', GETDATE())
DECLARE #newint int
SET #newint = SCOPE_IDENTITY()
UPDATE Test
SET Someday = #NextDate
WHERE ID = #newint
RESULT
But keeps giving the error with the result.
Msg 512, Level 16, State 1, Line 4
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
INSERT INTO #NextDate SELECT DATEADD(day,10,Today) FROM Test
In Your Query
SELECT #NextDate = (SELECT DATEADD(day,10,Today) FROM Test)
the sub query returning more than one value and you cant assign the multiple values to one variable. this is causing the problem in you query.
As Dominic Deepan.d Suggested use the where condition
SELECT #NextDate = (SELECT DATEADD(day,10,Today) FROM Test WHERE ID = #newint)
Or else try the same in another way
SELECT #NextDate = DATEADD(day,10,Today) FROM Test WHERE ID = #newint
Well Finally i sorted it out, Silly me :D
INSERT INTO Test(Notes,Today)
values ('Testing in Query3',GETDATE())
DECLARE #newint int
SET #newint = SCOPE_IDENTITY()
DECLARE #NextDate date
SELECT #NextDate = (SELECT DATEADD(day,10,Today) FROM Test WHERE ID = #newint)
UPDATE Test
SET Someday = #NextDate
WHERE ID = #newint
GO
I juz had to put WHERE in this line
SELECT #NextDate = (SELECT DATEADD(day,10,Today) FROM Test WHERE ID = #newint)
I have a query in a stored procedure, it works fine. now I want to add a column the it show error.
My stored procedure code is:
ALTER PROCEDURE dbo.test
#SDate DATETIME =Null
, #EDate DATETIME=Null
,#period int=Null
AS BEGIN
SET NOCOUNT ON;
if #period = 1
Begin
SELECT
t.TotalQuote
, t.QuoteAmount
,t.avgProbQ
, t2.TotalOrders
, t2.OrderAmount
,t3.totalSales
,t3.Prob
FROM (SELECT a = 1) a
CROSS JOIN (
SELECT
TotalQuote = COUNT(quoteid)
, QuoteAmount = SUM(totalamount)
,avgProbQ=SUM(CloseProbability)/COUNT(CloseProbability)
FROM dbo.QuoteBase join dbo.OpportunityBase on dbo.QuoteBase.opportunityid=dbo.OpportunityBase.opportunityid
WHERE
Month(dbo.QuoteBase.CreatedOn)=Month(getdate()) And YEAR(dbo.QuoteBase.CreatedOn)=YEAR(GETDATE())
) t
CROSS JOIN (
SELECT
TotalOrders = COUNT(salesorderid)
, OrderAmount = SUM(totalamount)
FROM dbo.SalesOrderBase join dbo.OpportunityBase on dbo.SalesOrderBase.Opportunityid=dbo.OpportunityBase.Opportunityid
Where Month(dbo.SalesOrderBase.CreatedOn)=Month(getdate()) And YEAR(dbo.SalesOrderBase.CreatedOn)=YEAR(GETDATE())
) t2
CROSS Join(
SELECT
TotalSales=COUNT(dbo.OpportunityBase.opportunityid)
,Prob=SUM(CloseProbability)/COUNT(CloseProbability)
FROM dbo.OpportunityBase join dbo.SalesorderBase on dbo.SalesOrderBase.Opportunityid=dbo.OpportunityBase.Opportunityid
WHERE Month(dbo.OpportunityBase.CreatedOn)=Month(getdate()) And YEAR(dbo.OpportunityBase.CreatedOn)=YEAR(GETDATE())
And dbo.SalesorderBase.StateCode=4
)t3
END
It works fine but when I add a new column like t.test, then it shows error
Msg 207, Level 16, State 1, Procedure test, Line 23
Invalid column name 'test'.
If anyone has an idea please share with me
I am not sure what is your table looked like
it seems you are adding test to your stored procedure but its not added in your database table
This is what I can say by looking the error message. Hope it helps
Not sure what you are trying to do, but guessing, if you are trying to add a column to the output of stored procedure, that is not in the table that the stored procedure is reading data from, then you have to put a literal expression into the select clause, with a defined column name like below: This example uses a string literal, but it can be any datatype...
SELECT 'A String literal to be added to output' As NewColumnName,
t.TotalQuote
, t.QuoteAmount
,t.avgProbQ
, t2.TotalOrders
, t2.OrderAmount
,t3.totalSales
,t3.Prob
etc....
You're getting this error because the column test does not exist in this query:
CROSS JOIN (
SELECT
TotalQuote = COUNT(quoteid)
, QuoteAmount = SUM(totalamount)
,avgProbQ=SUM(CloseProbability)/COUNT(CloseProbability)
FROM dbo.QuoteBase join dbo.OpportunityBase on dbo.QuoteBase.opportunityid=dbo.OpportunityBase.opportunityid
WHERE
Month(dbo.QuoteBase.CreatedOn)=Month(getdate()) And YEAR(dbo.QuoteBase.CreatedOn)=YEAR(GETDATE())
) t
but, if you were to add to that query a column named test then it would succeed. It could be a string literal like 'Some literal value' AS test if necessary.