get OBJECT_ID in linked server - tsql

Second select (from linked server) does not return any values.. Object_ID doesnt work. Is any workaround?
select '', name
FROM sys.databases
WHERE 1 = 1
AND NAME <> db_name() -- exclude current database
AND CASE
WHEN STATE = 0
THEN CASE
WHEN OBJECT_ID(NAME + '.dbo.tPA_SysParam', 'U') IS NOT NULL
THEN 1
END
END = 1
union
select '[LINKED]', name
FROM [LINKED].master.sys.databases
WHERE 1 = 1
AND CASE
WHEN STATE = 0
THEN CASE
WHEN OBJECT_ID('[LINKED].'+NAME + '.dbo.tPA_SysParam', 'U') IS NOT NULL
THEN 1
END
END = 1

You can also mimic OBJECT_ID with a little help from the PARSENAME function:
Declare #FullTableName nvarchar(max) = '[dbo].[MyTable]';
Select t.object_id
From [LINKED].MyDatabase.sys.tables As t
Inner Join [LINKED].MyDatabase.sys.schemas As s On t.schema_id = s.schema_id
Where t.[name] = PARSENAME(#FullTableName, 1)
And s.[name] = PARSENAME(#FullTableName, 2)

Related

How can I update a table using the following CROSS APPLY?

UPDATE ItemDim_DEV
set ActiveFlag = 0,
EndUTCDate = GETUTCDATE()
from (select i.SKU, i.itemname, i.category, i.CategoryInternalId, i.itemtype, i.IsActive, i.assetaccount, i.InternalId,
ni.sku,
ni.itemname,
ni.class_name,
ni.productclass,
ni.ItemType,
ni.isactive,
ni.assetaccount,
i.CalculatedHash, ni.hashid
from (
SELECT i.*
FROM itemDim_Dev i
WHERE i.SourceSystem = 'NetSuite'
--and InternalId = '1692'
) i
CROSS APPLY (
SELECT (CONVERT([binary](64),hashbytes('SHA2_512',
concat (ISNULL(im.TargetSKU, ni.sku), ni.itemname, pc.class_name, ni.productclass, ni.ItemType,
CAST(CASE WHEN ni.IsInactive = 'T' THEN 0 ELSE 1 END AS BIT ), ni.assetaccount)))) hashid,
ISNULL(im.TargetSKU, ni.sku) sku,
ni.itemname,
pc.class_name,
ni.productclass,
ni.ItemType,
CAST(CASE WHEN ni.IsInactive = 'T' THEN 0 ELSE 1 END AS BIT ) isactive, ni.assetaccount
FROM NetSuiteInventory ni
INNER JOIN Product_Class pc ON ni.productclass = pc.class_id
LEFT JOIN ItemMapping im ON ni.sku = im.SourceSKU
WHERE ni.ItemInternalId = CAST(i.InternalId as bigint)
and
(CONVERT([binary](64),hashbytes('SHA2_512',
concat (ISNULL(im.TargetSKU, ni.sku), ni.itemname, pc.class_name, ni.productclass, ni.ItemType,
CAST(CASE WHEN ni.IsInactive = 'T' THEN 0 ELSE 1 END AS BIT ), ni.assetaccount)))) = i.CalculatedHash
) ni
I understand that I can put a select after the from of the update but in the CROSS APPLY that is in the query starts with a select as in the second one, can you help me please.
Make a join to the target table
UPDATE A
SET XXX = YYY
FROM ItemDim_DEV A
JOIN (
--huge SELECT that I recommend you try to shorten in the next questions
CROSS APPLY (any secrets...)
) B ON A.PK = B.PK

How to select fields using alias name?

I have an select:
SELECT
tb_dim_equipe.no_equipe "EQUIPE",
tb_dim_profissional.no_profissional "PROFISSIONAL",
no_cidadao "CIDADÃO",
a.nu_cns "CNS",
sum(case when co_dim_tempo >= 20190100 and co_dim_tempo <= 20200131 then 1 else 0 end) as "TOTAL"
from (
SELECT no_cidadao,
tb_fat_cad_individual.nu_cns,
tb_fat_cad_individual.co_dim_profissional,
tb_fat_cad_individual.co_dim_equipe from tb_fat_cidadao_pec
join tb_fat_cad_individual on tb_fat_cad_individual.nu_cns = tb_fat_cidadao_pec.nu_cns
join tb_fat_cidadao on tb_fat_cad_individual.co_seq_fat_cad_individual = tb_fat_cidadao.co_fat_cad_individual
where st_mudou = 0
and st_vivo = 1
and st_gestante = 1
and tb_fat_cidadao.co_dim_tempo_validade = 30001231) a
left join (
SELECT tb_fat_atendimento_individual.nu_cns,
tb_fat_atendimento_individual.co_dim_tempo
from tb_fat_atendimento_individual
join tb_dim_tempo on tb_dim_tempo.co_seq_dim_tempo = tb_fat_atendimento_individual.co_dim_tempo
where co_seq_dim_tempo >= 20190100
and co_seq_dim_tempo <= 20200131
and ds_filtro_ciaps like '%ABP001%'
union SELECT tb_fat_proced_atend.nu_cns,
tb_fat_proced_atend.co_dim_tempo
from tb_fat_proced_atend
join tb_dim_tempo on tb_dim_tempo.co_seq_dim_tempo = tb_fat_proced_atend.co_dim_tempo
where co_seq_dim_tempo >= 20190100
and co_seq_dim_tempo <= 20200131
and ds_filtro_procedimento like '%0301010110%') b
on a.nu_cns = b.nu_cns
join tb_dim_equipe on tb_dim_equipe.co_seq_dim_equipe = a.co_dim_equipe
join tb_dim_profissional on tb_dim_profissional.co_seq_dim_profissional = a.co_dim_profissional
group by no_equipe, no_profissional, no_cidadao, a.nu_cns
order by no_equipe, no_profissional, no_cidadao
This return to me five columns EQUIPE, PROFISSIONAL, CIDADÃO, CNS and TOTAL
I want to create a new select command like this:
SELECT sum(c.TOTAL) from *query above* c
but I receive the error that column not exists.
How I can use a select with the names of alias columns EQUIPE, PROFISSIONAL, CIDADÃO, CNS and TOTAL?
Just like in the alias, you need to quote the column identifier if it is all-uppercase:
SELECT sum(c."TOTAL") from /*query above*/ c
-- ^ ^

How to append CTE results to main query output?

I've created a TSQL query that pulls from two sets of tables in my database. The tables in the Common Table Expression are different from the tables in the main query. I'm joining on MRN and need the end result to contain accounts from both sets of tables. I've written the following query to this end:
with cteHosp as(
select Distinct p.EncounterNumber, p.MRN, p.AdmitAge
from HospitalPatients p
inner join Eligibility e on p.MRN = e.MRN
inner join HospChgDtl c on p.pt_id = c.pt_id
inner join HospitalDiagnoses d on p.pt_id = d.pt_id
where p.AdmitAge >=12
and d.dx_cd in ('G89.4','R52.1','R52.2','Z00.129')
)
Select Distinct a.AccountNo, a.dob, DATEDIFF(yy, a.dob, GETDATE()) as Age
from RHCCPTDetail c
inner join RHCAppointments a on c.ClaimID = a.ClaimID
inner join Eligibility e on c.hl7Id = e.MRN
full outer join cteHosp on e.MRN = cteHosp.MRN
where DATEDIFF(yy, a.dob, getdate()) >= 12
and left(c.PriDiag,7) in ('G89.4','R52.1','R52.2', 'Z00.129')
or (
DATEDIFF(yy, a.dob, getdate()) >= 12
and LEFT(c.DiagCode2,7) in ('G89.4','R52.1','R52.2','Z00.129')
)
or (
DATEDIFF(yy, a.dob, getdate()) >= 12
and LEFT(c.DiagCode3,7) in ('G89.4','R52.1','R52.2','Z00.129')
)
or (
DATEDIFF(yy, a.dob, getdate()) >= 12
and LEFT(c.DiagCode4,7) in ('G89.4','R52.1','R52.2','Z00.129')
)
order by AccountNo
How do I merge together the output of both the common table expression and the main query into one set of results?
Merge performs inserts, updates or deletes. I believe you want to join the cte. If so, here is an example.
Notice the cteBatch is joined to the Main query below.
with
cteBatch (BatchID,BatchDate,Creator,LogID)
as
(
select
BatchID
,dateadd(day,right(BatchID,3) -1,
cast(cast(left(BatchID,4) as varchar(4))
+ '-01-01' as date)) BatchDate
,Creator
,LogID
from tblPriceMatrixBatch b
unpivot
(
LogID
for Logs in (LogIDISI,LogIDTG,LogIDWeb)
)u
)
Select
0 as isCurrent
,i.InterfaceID
,i.InterfaceName
,b.BatchID
,b.BatchDate
,case when isdate(l.start) = 0 and isdate(l.[end]) = 0 then 'Scheduled'
when isdate(l.start) = 1 and isdate(l.[end]) = 0 then 'Running'
when isdate(l.start) = 1 and isdate(l.[end]) = 1 and isnull(l.haserror,0) = 1 then 'Failed'
when isdate(l.start) = 1 and isdate(l.[end]) = 1 and isnull(l.haserror,0) != 1 then 'Success'
else 'idunno' end as stat
,l.Start as StartTime
,l.[end] as CompleteTime
,b.Creator as Usr
from EOCSupport.dbo.Interfaces i
join EOCSupport.dbo.Logs l
on i.InterfaceID = l.InterfaceID
join cteBatch b
on b.logid = l.LogID

SQL Select where exclusive Or /Case

I need a query based on an exclusive Or statement for this I try using the case but I won't get a result in case of Null...
...
and b.[U_Periode] = CASE
when (b.U_Periode= #period) then #period
when (b.U_Periode is NULL ) then null
end
...
The Case that won't be catched is... if B.U_Status is null and b.U_Periode is null.
If the var Periode match the Value and the U_Status = 0 or 1
the only way getting this working for me was this:
...
and
ISNULL( b.[U_Status],'0') = CASE
when (b.U_Status= '1') then '1'
when (isnull( b.U_Status,'0')= '0') then '0'
end
and
ISNULL (b.[U_Periode],'01.01.1901') = CASE
when (b.U_Periode= #period) then #period
when (ISNULL (b.U_Periode,'01.01.1901') = '01.01.1901' ) then '01.01.1901'
end
are there any other better solutions for this?
Best regards
Oliver
Okay... here is my Problem
Table1
InsID ContractID
1 1
2 1
Table2
ID insid Period Status Count
1 1 null null 100
2 1 30.09.2015 1 500
3 2 null null 100
4 2 30.09.2015 1 500
Case '31.08.2015'
in total Value should be 200
in case of '30.09.2015'
the Value should be 1.000
XOR /OR will do the same in this case.
Value case '31.08.2015' = 200
value Case ' 30.09.2015 = 2200
So this is somesing like a subquery
left join (
[dbo].[Table2]b
inner join [dbo].[Table 3]K on k.DocEntry = b.DocEntry and CAST( k.U_CSetID as int) >0
)
on b.[U_InsID] in(select... but here I should have an if statement...
If there are results matching the Date join this
If not than join the result NULL is matching to periode...
Okay.. here is the complete query
the Table2 with the Date of 31.08.2015 should have one Record that include
B_STATUS = Null and B.Preiode = null and there is no available record with the U_Periode '31.08.2015' and a Staus ...
with a date of 30.09.2015
there is a Record matching U_Period = '30.09.2015' in this case the Record with U_Period=null should not effect the result...
Declare #period as varchar(20)= '31-08-2015 00:00:00'
declare #Customer as Varchar(15)='12345'
declare #Contract as varchar(30) = '123'
declare #test as varchar(1) = null
select SUM(cast(K.U_Count as decimal))as counter, K.U_CounterTyp
from [dbo].[Table1] a
left join (
[dbo].[Table2]b
inner join [dbo].[Table 3]K on k.DocEntry = b.DocEntry and CAST( k.U_CSetID as int) >0
)
on b.[U_InsID]=a.[insID] and b.[U_ObjectType]in ('5','1') and
ISNULL( b.[U_Status],'0') = CASE
when (b.U_Status= '1') then '1'
when (isnull( b.U_Status,'0')= '0') then '0'
end
and
ISNULL (b.[U_Periode],'01.01.1901') = CASE
when (b.U_Periode= #period) then #period
when (ISNULL (b.U_Periode,'01.01.1901') = '01.01.1901' ) then '01.01.1901'
end
where a.[customer] =#Customer and a.[Status]='A' and a.[U_ContrCount]='1'
and a.[manufSN] in(
select c.[ManufSN] from [dbo].[Table4] c
inner join [dbo].[OCTR]d on d.[ContractID] = c.[ContractID]
where c.[ManufSN]=a.[manufSN]
and d.[CstmrCode] = a.[customer] and d.[ContractID]=#Contract
)
group by K.U_CounterTyp
you must use the "^" operand, this is XOR operand in TSQL
expression ^ expression
the expression must return or 0 or 1...
stupid example:
WHERE (name like "stackoverflow") ^ (age > 10)
font: https://msdn.microsoft.com/en-us/library/ms190277(v=sql.105).aspx
Update for your check
WHERE (CONVERT(VARCHAR(10), a.[U_Periode], 104) = '30.08.2015') != (a.U_Periode IS NULL)
Olay here is my funktion that chek either a Date Result is there or not.
The only thing is, that the performance is not the best if I run hundreths of sentences ... foreach record (up to app. 1000) I need to query each subtable... and there are many many records in...
Anyway this is the function
CREATE FUNCTION fn_GetInsCounters(#InsId as Varchar(30), #Date as datetime)
returns datetime
as
begin
declare #count as int = 0
declare #Retruns as Datetime
set #count =
(
select count( b.Docentry)
from [dbo].[Table2]b
where b.U_Insid =#InsID
and b.U_Status <> '2'
and b.[U_ObjectType]in ('5','1')
and b.U_Periode=#Date
)
if(#count>0)
begin
set #Retruns = #date
end
else
begin
set #Retruns = '01.01.1901'
end
return #Retruns
end
if anyone gets a better idea???
Best regards
Oliver

Can you use a SELECT INTO statement with a CTE that contains a UDF?

Can I do this:
With ZipCodeCTE as
{
select nvl(HH.GeoUSZip5 , **ZipCodeKeyLookUp**(HH.[CityName],HH.[StateName])) as TotalZipCode
from ODSDataArchive.archive.HHJob_Data_201202 HH
}
/* This Is a SELECT INTO statement that inserts
data into [Jobs].[dbo].[FactRPP]*/
SELECT [dbo].[FactJobsDaily].jobdid,
[dbo].[FactJobsDaily].DateKey,
[dbo].[FactJobsDaily].YearMonth,
[dbo].[FactJobsDaily].AccountKey,
[dbo].[FactJobsDaily].BridgeSocKey,
[dbo].[FactJobsDaily].HostSiteKey,
[dbo].[FactJobsDaily].JobClickedCount,
[dbo].[FactJobsDaily].JobResultsPageCount,
(select DZ.ZipCodeKey
from dimensions.dbo.DimZipCode DZ
where DZ.ZipCodeKey IN
(Select CAST(TotalZipCode AS INT)
from ZipCodeCTE))
INTO [Jobs].[dbo].[FactRPP]
from dbo.FactJobsDaily
inner join ODSDataArchive.archive.HHJob_Data_201202
on dbo.FactJobsDaily.JobDID = ODSDataArchive.archive.HHJob_Data_201202.DID
and dbo.FactJobsDaily.datekey = ODSDataArchive.archive.HHJob_Data_201202.datekey
inner join dimensions.dbo.Dimzipcode dzc
on ODSDataArchive.archive.HHJob_Data_201202.geoUSZip5 = dimensions.dbo.Dimzipcode.ZipCode
where [dbo].[FactJobsDaily].yearmonth= 201202
and [dbo].[FactJobsDaily].isactivekey = 1
-- and ODSDataArchive.archive.HHJob_Data_201202.geoUSZip5 <> ''
-- and ODSDataArchive.archive.HHJob_Data_201202.geoUSZip5 IS NOT NULL
and ODSDataArchive.archive.HHJob_Data_201202.status = 0
and ODSDataArchive.archive.HHJob_Data_201202.CountryName = 'US'
order by [dbo].[FactJobsDaily].jobdid;
Because the CTE translates into a regular query the short answer is yes.