Invalid Object Name when i execute a procedure that update a table - sql

I have the following
use salesdb
go
create procedure monthlysales as
begin
create table MyTable( SalesFactID integer identity(1,1),
ReportingMth date,
customer_id varchar(50),
ReferenceID navarchar(50),
LstOrderDte date);
Insert into MyTable
select
businessMth,
saleid as referenceid,
null as lastorderte
from sourcetble;
update MyTable
set lastorderte = sls.max_orderdte
from ( select
st.customer_id,
ftmytbl.ReportingMth,
max(salesdate) as max_orderdte
from sales_table st
left outer join mytable ftmytbl
on ftmytbl.customerid=st.customerRef
where saleste<=ftmytbl.ReportingMth
group by customer_id
)up
where mytable.customer_id=up.customer_id
and mytable.reportingmth=up.ReportingMth;
end;
execute monthlysales
error invalid object name mytable.reportingmth
How can i fix this? Please assist.

Search for that text. Where is it? It is in the where clause of the outermost select statement. You used a derived table named up (which is a crap name, btw - as are many of your names) in the join. The outer query knows only 2 tables - up and MyTable (or is it mytable? BE CONSISTENT!) and can only refer to columns in those tables.
To correct this particular problem, change this:
and mytable.reportingmth=up.ReportingMth;
to
and MyTable.ReportingMth = up.ReportingMth;
But that will only fix one problem. There seem to be others yet to be found.

Related

Select all values in 1 view ( can't use procedure and temp tables)

I need to create a View with select in my database. It must be view can't use stored procedure so it needs to be created in just one query without temp tales.
I create a simple example:
CREATE TABLE #TemporaryTable -- Local temporary table - starts with single #
(
id int,
date_order date,
order_status varchar(50)
);
insert into #TemporaryTable
VALUES
('1','2022-01-01','Completed'),
('2','2022-01-01','Cancelled'),
('3','2022-01-01','Completed'),
('4','2022-01-01','Completed'),
('5','2022-01-02','Cancelled'),
('6','2022-01-02','Cancelled'),
('7','2022-01-02','Completed'),
('8','2022-01-02','Completed'),
('9','2022-01-02','Completed'),
('10','2022-01-03','Cancelled'),
('11','2022-01-04','Completed')
select * from #TemporaryTable
SELECT COUNT(crm1.date_order) AS [count_all_orders], crm1.date_order AS [date_order],COUNT(crm2.date_order) AS [[count_cancelled_orders]
FROM #TemporaryTable crm1 WITH (nolock)
left outer join #TemporaryTable crm2 WITH (nolock) on crm2.id = crm1.id and crm2.order_status ='Cancelled'
GROUP BY crm1.date_order,crm2.date_order
SQL fiddle
The endpoint is to have 1 date and count all orders + count cancelled orders.
Now the date is doubled and giving bad values. Please check that in SQL fiddle and help me.
Thank you!
There is no need to join, you can simply use conditional aggregation:
COUNT(someNonNullValue) and COUNT(*) are the same thing
SELECT
COUNT(*) AS count_all_orders,
crm1.date_order,
COUNT(CASE WHEN crm2.order_status = 'Cancelled' THEN 1 END) AS count_cancelled_orders
FROM #TemporaryTable crm
GROUP BY
crm.date_order;
NOLOCK is a very bad idea. Only use it in exceptional circumstances.

How to copy the column id from another table?

I'm stuck with this since last week. I have two tables, where the id column of CustomerTbl correlates with CustomerID column of PurchaseTbl:
What I'm trying to achieve is I want to duplicate the data of the table from itself, but copy the newly generated id of CustomerTbl to PurchaseTbl's CustomerID
Just like from the screenshots above. Glad for any help :)
You may use OUTPUT clause to access to the new ID. But to access to both OLD ID and NEW ID, you will need to use MERGE statement. INSERT statement does not allow you to access to the source old id.
first you need somewhere to store the old and new id, a mapping table. You may use table variable or temp table
declare #out table
(
old_id int,
new_id int
)
then the merge statement with output clause
merge
#CustomerTbl as t
using
(
select id, name
from CustomerTbl
) as s
on 1 = 2 -- force it to `false`, not matched
when not matched then
insert (name)
values (name)
output -- the output clause
s.id, -- old_id
inserted.id -- new_id
into #out (old_id, new_id);
after that you just use the #out to join back using old_id to obtain the new_id for the PurchaseTbl
insert into PurchaseTbl (CustomerID, Item, Price)
select o.new_id, p.Item, p.Price
from #out o
inner join PurchaseTbl p on o.old_id = p.CustomerID
Not sure what your end game is, but one way you could solve this is this:
INSERT INTO purchaseTbl ( customerid ,
item ,
price )
SELECT customerid + 3 ,
item ,
price
FROM purchaseTbl;

SQL Using subquery in where clause and use values in select

I can not figure out how to get it done where I have a main select list, in which I want to use values which I select in a sub query in where clause..My query have join statements as well..loosely code will look like this
if object_id('tempdb..#tdata') is not null drop table #tdata;
go
create table #tdata(
machine_id varchar(12),
temestamp datetime,
commit_count int,
amount decimal(6,2)
);
if object_id('tempdb..#tsubqry') is not null drop table #tsubqry;
go
--Edit:this is just to elaborate question, it will be a query that
--will return data which I want to use as if it was a temp table
--based upon condition in where clause..hope makes sense
create table #tsubqry(
machine_id varchar(12),
temestamp datetime,
amount1 decimal(6,2),
amount2 decimal(6,2)
);
insert into #tdata select 'Machine1','2018-01-02 13:03:18.000',1,3.95;
insert into #tdata select 'Machine1','2018-01-02 02:11:19.000',1,3.95;
insert into #tdata select 'Machine1','2018-01-01 23:18:16.000',1,3.95;
select m1.machine_id, m1.commit_count,m1.amount,***tsub***.amount1,***tsub***.amount2
from #tdata m1, (select amount1,amount2 from #tsubqry where machine_id=#tdata.machine_id) as ***tsub***
left join sometable1 m2 on m1.machine_id=m2.machine_id;
Edit: I have tried join but am getting m1.timestamp could not be bound as I need to compare these dates as well, here is my join statement
from #tdata m1
left join (
select amount1,amount2 from #tsubqry where cast(temestamp as date)<=cast(m1.temestamp as date)
) tt on m1.machine_id=tt.machine_id
Problem is I want to use some values which has to be brought in from another table matching a criteria of main query and on top of that those values from another table has to be in the column list of main query..
Hope it made some sense.
Thanks in advance
There seems to be several things wrong here but I think I see where you are trying to go with this.
The first thing I think you are missing is is the temestamp on the #tsubqry table. Since you are referencing it later I'm assuming it should be there. So, your table definition needs to include that field:
create table #tsubqry(
machine_id varchar(12),
amount1 decimal(6,2),
amount2 decimal(6,2),
temestamp datetime
);
Now, in your query I think you were trying to use some fields from #tdata in your suquery... Fine in a where clause, but not a from clause.
Also, I'm thinking you will not want to duplicate all the data from #tdata for each matching #tsubqry, so you probably want to group by. Based on these assumptions, I think your query needs to look something like this:
select m1.machine_id, m1.commit_count, m1.amount, sum(tt.amount1), sum(tt.amount2)
from #tdata m1
left join #tsubqry tt on m1.machine_id=tt.machine_id
and cast(tt.temestamp as date)<=cast(m1.temestamp as date)
group by m1.machine_id, m1.commit_count, m1.amount
MS SQL Server actually has a built-in programming construct that I think would be useful here, as an alternative solution to joining on a subquery:
-- # ###
-- # Legends
-- # ###
-- #
-- # Table Name and PrimaryKey changes (IF machine_id is NOT the primary key in table 2,
-- # suggest make one and keep machine_ie column as an index column).
-- #
-- #
-- # #tdata --> table_A
-- # #tsubqry --> table_B
-- #
-- =====
-- SOLUTION 1 :: JOIN on Subquery
SELECT
m1.machine_id,
m1.commit_count,
m1.amount,
m2.amount1,
m2.amount2
FROM table_A m1
INNER JOIN (
SELECT machine_id, amount1, amount2, time_stamp
FROM table_B
) AS m2 ON m1.machine_id = m2.machine_id
WHERE m1.machine_id = m2.machine_id
AND CAST(m2.time_stamp AS DATE) <= CAST(m1.time_stamp AS DATE);
-- SOLUTION 2 :: Use a CTE, which is specific temporary table in MS SQL Server
WITH table_subqry AS
(
SELECT machine_id, amount1, amount2, time_stamp
FROM table_B
)
SELECT
m1.machine_id,
m1.commit_count,
m1.amount,
m2.amount1,
m2.amount2
FROM table_A m1
LEFT JOIN table_subqry AS m2 ON m1.machine_id = m2.machine_id
WHERE m1.machine_id = m2.machine_id
AND CAST(m2.time_stamp AS DATE) <= CAST(m1.time_stamp AS DATE);
Also, I created an SQLFiddle in case it's helpful. I don't know what all your data looks like, but at least this fiddle has your schema and runs the CTE query qithout any errors.
Let me know if you need any more help!
SQL Fiddle
Source: Compare Time SQL Server
SQL SERVER Using a CTE
Cheers.

Insert Into using a WITH clause (CTE) causes a ORA-00928

I'm attempting to do an essentially very simple task, which is resulting in:
ORA-00928: missing SELECT keyword
All I'm trying to do is persist the results from periods into table globalTable. Selecting works fine (I'm returned rows) however as soon as I replace it with the Insert I get the above error.
create global temporary table globalTable
(
ids number(11)
);
with periods as
(
select cl.id uniqueId
from inv_mpan_hh_con_lines cl
left join invoice_vat_lines vl on
cl.invoice_id = VL.INVOICE_ID
where rownum < 4
)
--//Issue occurs at insert keyword. If I comment it and uncomment select it works as expected//--
--select uniqueId
insert into globalTable
from periods;
Any pointers are much appreciated.
Try this:
insert into globalTable
with periods as
(
select cl.id uniqueId
from inv_mpan_hh_con_lines cl
left join invoice_vat_lines vl
on cl.invoice_id = VL.INVOICE_ID
where rownum < 4
)
select uniqueId
from periods;
CTE (WITH-clause) is a part of SELECT statement, according to the INSERT syntax you can either specify values or SELECT statement

How to create SQL Server stored procedure returning an array?

Sorry for this maybe foolish question but i'm newbie to SQL Server. Here structure of my table of divisions at organization:
id int(16) -- simply unique id
sub_id int(16) -- this id of parent division in this table (if zero, than it don't have parent)
name VARCHAR(200) -- name of division
I need to create a simply procedure which return me all id of subdivisions in some division (with top division id too). I think i need array with subid's in loop, but i don't know how to create array in SQL Serve o_0 (omg.. array exist in (T)SQL language ? =). Help please. Or maybe another way to get it?
If I have understood your question correctly you need a recursive CTE.
CREATE PROCEDURE dbo.foo
#id int
AS
WITH divisions AS
(
SELECT id, sub_id, name
FROM YourTable
WHERE id = #id
UNION ALL
SELECT y.id, y.sub_id, y.name
FROM YourTable y
JOIN divisions d ON d.id = y.sub_id
)
SELECT id, sub_id, name
FROM divisions
SELECT id
FROM table
WHERE sub_id = #target
UNION ALL
SELECT #target