Querying multiple databases using MSforeachDB - multiple-databases

I'm querying about 60+ databases using MSforeachdb. The query works when I run it on a single database but I get a syntax error when I use MSforeachdb. Here is the code i used to query one database:
SELECT
DISTINCT(PAMARTID)
,PAMSTAID
, Gender
, DaysToNextApp
, DATEDIFF(day, DateofVisit, DateOfNextApp) AS date_difference
,DateOfNextApp
, DateofVisit
, MONTH(DateofVisit) AS Month
, DATENAME(month, DateofVisit) AS Month_Name
, YEAR(DateofVisit)AS Year
, REGID
, Description
, ROUND (DaysToNextApp/28, 0) AS MMD
, DATEDIFF(month, DateofVisit, DateOfNextApp) AS MMD_based_on_difference
FROM dbo.PAM p JOIN dbo.LuRegimen r ON p.PAMREMID = r.REGID
WHERE PAMSTAID = 2 AND (DateofVisit BETWEEN '2021-10-1 00:00:00:000' AND '2022-09-30 00:00:00:000')
I then adapted it for use on multiple database:
DECLARE #sql AS VARCHAR (4000)
SET #sql = 'IF ''?'' NOT IN(''master'', ''model'', ''msdb'', ''tempdb'')
EXECUTE ('' USE \[?\]
SELECT
DISTINCT(PAMARTID)
,PAMSTAID
, Gender
, DaysToNextApp
, DATEDIFF(day, DateofVisit, DateOfNextApp) AS date_difference
,DateOfNextApp
, DateofVisit
, MONTH(DateofVisit) AS Month
, DATENAME(month, DateofVisit) AS Month_Name
, YEAR(DateofVisit)AS Year
, REGID
, Description
, ROUND (DaysToNextApp/28, 0) AS MMD
, DATEDIFF(month, DateofVisit, DateOfNextApp) AS MMD_based_on_difference
FROM dbo.PAM p JOIN dbo.LuRegimen r ON p.PAMREMID = r.REGID
WHERE PAMSTAID = 2 AND (DateofVisit BETWEEN ''2021-10-1 00:00:00:000'' AND ''2022-09-30 00:00:00:000'')'')'
EXEC sp_MSforeachdb #command1 = #sql
however the above gives a the following error:
Msg 102, Level 15, State 1, Line 19
Incorrect syntax near '2021'.
I removed the the following piece of code
AND (DateofVisit BETWEEN ''2021-10-1 00:00:00:000'' AND ''2022-09-30 00:00:00:000'')
from the sp-MSforeachdb query and it worked but if I add it again I get the aforementioned error
Any help or alternative methods would be appreciated.

Related

Incorrect parameter count in the call to native function 'DATE_FORMAT' from Oracle to Mysql

I have Oracle script and I want to transform it from Oracle query into mysql query.
With the help of SQLines and documentation reading, I came up from Oracle Format :
nvl(TO_NUMBER(TO_CHAR(ADD_MONTHS(T156431.PERIOD_START, -6), 'yyyy'), '9999') , 1970) as c13
to Mysql Format :
ifnull(cast(DATE_FORMAT(TIMESTAMPADD(MONTH, -6, T156431.PERIOD_START), '%Y') as SIGNED), 1970) as c13
but when I try to run the mysql format, I endup with this error and I don't know what caused it :
Incorrect parameter count in the call to native function 'DATE_FORMAT'
So where did I go wrong?
Here is the full mysql script (The problem is at line 14)
SELECT
sum(T156033.PO_AMOUNT / 1000000.0) as c1,
sum(T156033.PO_AMOUNT / 1000.0) as c2,
sum(T156033.PO_AMOUNT / 1.0) as c3,
concat(concat(T156375.ACTIVITIES_R, ' '), T156375.ACTIVITIES_ALIAS_R) as c4,
T156375.ACTIVITIES_R as c5,
T156375.ACTIVITIES_ALIAS_R as c6,
T155910.AP_CODE_R as c7,
concat(concat(T156431.JSP_PLAN_ID_WO_FY, ' '), T156431.JSP_PLAN_NAME) as c8,
T156431.PERIOD_START as c9,
IFNULL(T155910.AP_CATEGORY_R , 'Unknown A&P Category') as c10,
IFNULL(case IFNULL(T155910.AP_CAT_COMM , 'UNKNOWN') when 'OPEX_AP' then 'Opex' when 'CAPE' then 'Capex' else 'Unknown' end , 'Unknown AP') as c11,
IFNULL(T156431.PLAN_TYPE , 'Unknown') as c12,
ifnull(cast(DATE_FORMAT(TIMESTAMPADD(MONTH, -6, T156431.PERIOD_START), '%Y') as SIGNED), 1970) as c13
FROM
(SELECT MFM_PROMOTION_HEADER.*, SUBSTRING(MFM_PROMOTION_HEADER.JSP_PLAN_ID,1, CASE WHEN LOCATE(MFM_PROMOTION_HEADER.JSP_PLAN_ID,'_') = 0 THEN CHAR_LENGTH(RTRIM(MFM_PROMOTION_HEADER.JSP_PLAN_ID)) ELSE LOCATE(MFM_PROMOTION_HEADER.JSP_PLAN_ID,'_') -1 END) AS JSP_PLAN_ID_WO_FY FROM MFM_PROMOTION_HEADER_VIEW MFM_PROMOTION_HEADER WHERE MFM_PROMOTION_HEADER.MARKET_CODE IN ('IT')) T156431,
(SELECT MARKET_CODE, AP_TREE, AP_TREE_R, AP_TREE_ALIAS, AP_TREE_ALIAS_R, AP_CATEGORY, AP_CATEGORY_R, AP_CATEGORY_ALIAS, AP_CATEGORY_ALIAS_R, AP_TYPE, AP_TYPE_R, AP_TYPE_ALIAS, AP_TYPE_ALIAS_R, AP_CODE, AP_CODE_R, AP_CODE_ALIAS, AP_CODE_ALIAS_R, FV_IND, AP_CAT_COMM, AP_CAT_COST FROM SGT_DIM_AP_CODE WHERE MARKET_CODE IN ('IT')) T155910,
(SELECT * FROM SGT_DIM_ACTIVITY WHERE MARKET_CODE IN ('IT')) T156375,
(SELECT RIGHT (REPEAT('0', 8) + LEFT ((CASE WHEN IFNULL(t2.customer, 'XXXX') = 'XXXX' THEN SUBSTRING (t1.CUSTOMER,1,LOCATE('_',t1.CUSTOMER)-1) ELSE SUBSTRING(t2.CUSTOMER,1,LOCATE('_',t2.CUSTOMER)-1) END), 8 ), 8 ) as customer_po, t1.*, (CASE WHEN t1.PO_EQUV_AMOUNT = 0 THEN 0 ELSE t1.PO_AMOUNT/t1.PO_EQUV_AMOUNT END) as ACTUAL_FX, ( CASE WHEN t1.PO_CURRENCY = 'RMB' THEN t1.PO_EQUV_AMOUNT ELSE t1.PO_AMOUNT/1.260924 END ) AS PO_AMOUNT_DF, t1.PO_EXCH_RATE * t1.PAYMENT_PAID_AMOUNT as PAYMENT_PAID_AMOUNT_HKD from mfm_po_jsp t1 left join MFM_CUSTOMER_MAPPING t2 on t2.market_code = t1.market_code and RIGHT((REPEAT ('0', 8)) + LEFT (t2.sub_ledger, 8) , 8 ) = RIGHT ((REPEAT ('0', 8)) + LEFT (SUBSTRING(t1.CUSTOMER,1,LOCATE('_',t1.CUSTOMER)-1), 8) , 8 ) ) T156033
WHERE T156033.JSP_PLAN_ID = T156431.JSP_PLAN_ID and T155910.AP_CODE = T156033.AP_CODE and T155910.MARKET_CODE = T156033.MARKET_CODE and T156033.MARKET_CODE = T156431.MARKET_CODE and T156033.ACTIVITIES = T156375.ACTIVITIES and T156033.MARKET_CODE = T156375.MARKET_CODE and YEAR(DATE_FORMAT(TIMESTAMPADD(MONTH,-6,T156431.PERIOD_START))) = 2021
GROUP BY T155910.AP_CODE_R, T156375.ACTIVITIES_ALIAS_R, T156375.ACTIVITIES_R, T156431.PERIOD_START, concat(concat(T156375.ACTIVITIES_R, ' '), T156375.ACTIVITIES_ALIAS_R), concat(concat(T156431.JSP_PLAN_ID_WO_FY, ' '), T156431.JSP_PLAN_NAME), IFNULL(T155910.AP_CATEGORY_R , 'Unknown A&P Category'), IFNULL(T156431.PLAN_TYPE , 'Unknown'), IFNULL(case IFNULL(T155910.AP_CAT_COMM , 'UNKNOWN') when 'OPEX_AP' then 'Opex' when 'CAPE' then 'Capex' else 'Unknown' end , 'Unknown AP')
Okay, so it seems the Error didn't came from the line I highlighted, but it came from another line.
From WHERE line
YEAR(DATE_FORMAT(TIMESTAMPADD(MONTH,-6,T156431.PERIOD_START))
and sure enough, it's missing some parameter to run the DATE_FORMAT Fuction, hence the error.

SSIS Package -Count based on multiple columns

I need to create an SSIS Package that provides me the count of workdoneby (contractor/company).
Input table from sql server db:
I need to count no of orders by contractor and company for a particular day + station + worktype + accountno.
My output should look like this.
Can someone help me how to create a package to get the desired output?
Since the data is in a table, you can ask the database engine to do the calculation logic.
Setup
I created a temporary table and populated it with the supplied data.
CREATE TABLE
#Source
(
[Date] date
, Station char(3)
, worktype char(2)
, Accountno varchar(10)
, workdoneby varchar(10)
)
INSERT INTO
#Source
(
Date
, Station
, worktype
, Accountno
, workdoneby
)
VALUES
('2018-06-24', 'RMS', 'RH', 'I.145.001', 'Company')
, ('2018-06-24', 'RMS', 'PH', 'I.145.001', 'Contractor')
, ('2018-06-24', 'RMS', 'PH', 'I.145.002', 'Company')
, ('2018-06-24', 'RMS', 'PH', 'I.145.002', 'Contractor');
Query time
Now let's query! I find it is helpful to break these problems down into smaller pieces. The first thing I want to do is break out the workdoneby column into two columns with a 1 or 0
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
Running that let's me look at the results and see I still have 4 rows and I get the correct entity counted.
The next step is to collapse/summarize/roll-up the values. You indicate we should group by date/station/worktype/accountno so that's exactly what we're going to to do.
I find it easier to debug if I take that first query and make it a derived table so the basic form now becomes SELECT * FROM (ORIGINAL QUERY HERE) AS D thus
SELECT
D.Date
, D.Station
, D.worktype
, D.Accountno
, D.contractorCount
, D.companyCount
FROM
(
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
) D
Now that you can see it's giving the same original results, we're going to use the SUM function on the contractorCount and companyCount columns and GROUP BY date/station/worktype/accountno
SELECT
D.Date
, D.Station
, D.worktype
, D.Accountno
, SUM(D.contractorCount) AS contractor
, SUM(D.companyCount) AS company
FROM
(
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
) D
GROUP BY
D.Date
, D.Station
, D.worktype
, D.Accountno;
SSIS
Now that we have data looking as expected, within SSIS you need to do something with it. Your question doesn't specify what you need to do but likely you're going to use a Data Flow Task to push this aggregated data from one place to another destination (different server, Excel, etc) or you're going to push this data into a table on the same server in which case you're going to use an Execute SQL Task

mysql between datetime shows wrong record

I have this query:
SELECT id
, order_date
, seat_number
, cashier_fk
, branch_fk
, waiter_fk
, void
, total_amount
, customer_name
, payment
, notes
, down_payment
, received_date
, void_reason
, discount
, discount_percentage
, printed
, done
, vat
, service_charge
FROM order_tbl
WHERE received_date between "2018-03-15" AND "2018-03-18"
but it shows
My table has this record:
id-------order_date
1-------2018-03-09 09:09:25
2-------2018-03-13 18:29:16
3-------2018-03-13 20:00:49
4-------2018-03-13 20:01:46
5-------2018-03-13 20:05:48
6-------2018-03-13 20:06:34
7-------2018-03-13 20:07:15
9-------2018-03-16 19:06:23
10-------2018-03-16 20:22:26
But it shows only
id-------order_date
5-------2018-03-13 20:05:48
6-------2018-03-13 20:06:34
7-------2018-03-13 20:07:15
9-------2018-03-16 19:06:23
10-------2018-03-16 20:22:26
What is wrong with my query?
Do not use between with dates or date/times. The time component throws everything off.
Instead, express the logic as:
WHERE received_date >= '2018-03-15' AND
received_date < '2018-03-19'
Note the inequality at the end of the range. This ensures that you get everything from that date.
Aaron Bertrand has a really good blog post on the subject, What do BETWEEN and the devil have in common?.

Age Calculation duplicate column using sql server 2008 R2

I have login table with DOB Column. I need duplicate column for age. But i can't do this. I can convert DOB column convert to Age for alone
`SELECT FLOOR(DATEDIFF(DAY,'10/10/1990' , getdate()) / 365.25)` works fine.
But I need to convert whole column.
If I'm Using
SELECT FLOOR(DATEDIFF(DAY,Select DOB From login_tbl , getdate()) / 365.25) like this,
It's throwing error. How can I get it?
Thankyou
Your approach will get wrong result in such cases below:
declare #now date
set #now = '11/10/2014'
select
FLOOR(DATEDIFF(DAY,'11/10/2013' , #now) / 365.25) -- should be 1 but will get 0
, FLOOR(DATEDIFF(DAY,'11/10/2012' , #now) / 365.25) -- should be 2 but will get 1
, DATEDIFF(DAY,'11/10/2013' , #now)
, DATEDIFF(DAY,'11/10/2012' , #now)
My suggestion is :
declare #now date
set #now = '11/10/2014'
select (convert(int,convert(varchar(8), #now ,112))
- convert(int,convert(varchar(8),convert(date,'11/10/2013'),112) ) )/10000
You could see my explain in this answer.
So for your login_tbl you could:
select
DOB, (convert(int,convert(varchar(8), DOB ,112))
- convert(int,convert(varchar(8),convert(date,'11/10/2013'),112) ) )/10000 as AGE
from
login_tbl
select trunc((trunc(sysdate) - to_date('16-mar-2010', 'dd-mon-yyyy'))/ (365.23076923074))
from dual

How to wirte a query for updating two tables at a time?

HI i have two tables in my database named...Requests and Balance tracker which has no relation....but i want to select data from two tables and binf it two grid...
Requests
EmpID |EmpRqsts|EmpDescription|ApproverID|ApprovedAmount|RequestPriority
1 |asdfsb |sadbfsbdf |1 |
2 |asbfd |sjkfbsd |1 |
Balance Tracker
EmpId|BalanceAmnt|LastUpdated|lastApprovedAmount
| 1 |5000 |sdfbk |
| 2 |3000 |sjbfsh |
now i want to update based on the EmpID two tables at a time...when ever amount is approved it should be updates in request table column [ApprovedAmount] and with priority...
when [ApprovedAmount] is Updated [BalanceAmnt] Balance Tracker of also should be Updated by adding the amount approved,[LastUpdated],[lastApprovedAmount] should be updated with date and time
can any one help me with the query please....
#Anil, here is an example of SQL Server 2008 code which would help you to get your goal acomplished:
DECLARE #Requests TABLE
(
EmpId int
, EmpRqsts nvarchar(50)
, EmpDescription nvarchar(250)
, ApproverID int
, ApprovedAmount money
, RequestPriority int
)
DECLARE #BalanceTracker TABLE
(
EmpId int
, BalanceAmnt money
, LastUpdated datetime
, lastApprovedAmount money
)
-- Insert data for testing
INSERT INTO #Requests VALUES
(
1
, 'Something here'
, 'Some descriptio here'
, 1
, 100
, 1
)
INSERT INTO #Requests VALUES
(
2
, 'Something here 2 '
, 'Some descriptio here 3'
, 1
, 215
, 2
)
INSERT INTO #BalanceTracker VALUES
(
1
, 5000
, GETDATE() - 3
, 310
)
INSERT INTO #BalanceTracker VALUES
(
2
, 3000
, (GETDATE() - 1)
, 98
)
-- Declare local variables
DECLARE
#NewAmount money
, #NewPriority int
, #SelectedEmpId int
-- Assing values for example
SELECT #NewAmount = 1000
, #SelectedEmpId = 1
, #NewPriority = 5
-- Get the tables values pre - updates
SELECT *
FROM #Requests
SELECT *
FROM #BalanceTracker
BEGIN TRY
-- Update the record with new ApprovedAmount and Request Priority
UPDATE #Requests
SET ApprovedAmount = #NewAmount
, RequestPriority = #NewPriority
WHERE EmpId = #SelectedEmpId
-- If no error found then update BalanceAmnt trable
IF (##ERROR = 0)
BEGIN TRY
UPDATE #BalanceTracker
SET BalanceAmnt = (BalanceAmnt + #NewAmount)
, LastUpdated = GETDATE()
, lastApprovedAmount = #NewAmount
WHERE EmpId = #SelectedEmpId
END TRY
BEGIN CATCH
PRINT N'Error found updating #BalanceTracker table: ' + ISNULL(LTRIM(STR(ERROR_NUMBER())) , N'Unknown Error' )
+ N', Message: ' + ISNULL ( ERROR_MESSAGE() , N'No Message' )
END CATCH
END TRY
BEGIN CATCH
PRINT N'Error found updating #Requests table: ' + ISNULL(LTRIM(STR(ERROR_NUMBER())) , N'Unknown Error' )
+ N', Message: ' + ISNULL ( ERROR_MESSAGE() , N'No Message' )
END CATCH
-- Get the tables values post - updates
SELECT *
FROM #Requests
SELECT *
FROM #BalanceTracker
Note 1: #Table are Variable Tables handlded by SQL Server 2008. If you're using previous version you should be able to create Temporary Table (#Table).
Note 2: data data-types may vary depending upon the SQL version you're using.
You could do this type of thing with a trigger. This way whenever you do the first update, it will automatically do the other update you specify.