Bind data from 2 datasets into one tablix in SSRS - reporting-services

I have to combine data from 2 different datasets to single Tablix which should be sorted on Date Time.
For Example:
Dataset1:
DateTime Product Employee
2020-08-13 18:10:53.263 ABC A
Dataset2:
DateTime Product Employee
2020-08-13 19:10:20.000 XYZ A
ResultSet:
DateTime Product Employee
2020-08-13 18:10:53.263 ABC A
2020-08-13 19:10:20.000 XYZ A
Note: I cannot combine data from both the datasets at the database level as the datasets refer to 2 different datasources.
I have an idea on LOOKUP but I guess that can be used at column level but my case I need to display the data at row level from 2 datasets based on Datetime sort.
Could someone please suggest if there is a way to achieve this.
Thank you in advance!!

If the databases are on the same server then you can simply UNION the results together something like
SELECT [DateTime], [Product], [Employee]
FROM [database_A].[mySchema].[myFirstTable]
UNION ALL
SELECT [DateTime], [Product], [Employee]
FROM [database_B].[myotherSchema].[myOtherFirstTable]
If they are on different servers then Create a linked server (details on how to do this are here)
Then use the same query but preceding the 2nd reference with the server name / link server name
SELECT [DateTime], [Product], [Employee]
FROM [database_A].[mySchema].[myFirstTable]
UNION ALL
SELECT [DateTime], [Product], [Employee]
FROM [myLinkedServerName].[database_B].[myotherSchema].[myOtherFirstTable]
Now you'll have a single dataset with all your data and no headache!
If you have two existing Stored Procs
If you have two SP then you can still do this but in a slightly different way. Something like
CREATE TABLE #t([DateTime] DateTime, Product varchar(50), Employee int)
INSERT INTO #t
EXEC #myFirstProc
INSERT INTO #t
EXEC #mySecondProc
SELECT * FROM #t

Related

In MS SQL Server mgt studio, is there a way to format select results like mysql \G

I would like to have the results of my query (that returns one row) to be displayed in text like this:
columnA: value
columnB: value
columnC: value
as happens in mysql when using
select * from tablename \G
Is there a way to do this? The reason for this is that it is helpful to be able to print out one record with columns and values for example data or to share a record from a table that has many columns and which would be hard to view across the screen.
It's not quite so simple as your MySQL example, but you can do an unpivot to get what you want.
---------------
-- TEST SCHEMA
---------------
declare #tablename as Table(keyvalue varchar(2), dataColA varchar(2), dataColB varchar(2), dataColC varchar(2))
insert into #tablename select '01', '02', '03', '04'
---------------
-- UNPIVOT
---------------
select dataColumns, dataValues
from #tablename
unpivot
(
dataValues
for dataColumns in (keyvalue, dataColA, dataColB, dataColC)
) u;
The easiest way to accomplish what I want is to
execute the query to a results grid, limit to top 1 if necessary to ensure only one row is returned,
right-click in top left corner, Copy with Headers
open Excel, paste
select what was just pasted and copy again within Excel
go to blank area of workbook or new worksheet and Paste Special, Transpose
This will create one row per database query column with column name in column A and value in column B.

SSIS amount of insert operations based on record value

I'm migrating data from an old database to a new one in SSIS (2008 R2 Enterprise Edition). In the old database, I have a table called [Financial] and a column named: [Installments]. This column has a numeric value in it: 1, 2, 3 or 4. These are payments in installments. The old database only stores this numeric value and do not provide any more information about individual installments. The new database, however, provide more information of each installment, with columns like: [InstallmentPaid] (if the customer paid the installment), [DateInstallmentPaid] (when the customer paid the installment), [InstallmentNumber] (this is important to specify which installmentnumber it is. If the customer wants to pay in 4 installments, then 4 records will be created. 1 with InstallmentNr1, second with InstallmentNr2, third with InstallmentNr3 and fourth with InstallmentNr4.) and of course the [InstallmentPrice].
So the old database has the table [Financial] with the column [Installments]. The new database has the same [Financial] table, but instead of having a column called [Installments], it has a new relationship called [CustInstallments] ([CustInstallments] has FK FinancialID (1-to-many relationship)
So now that I'm migrating the data from the old database to the new one, I don't want to lose the information about the amount of installments. The following logic should be executed in SSIS in order to prevent information loss:
Foreach [Installments] in [Financial] from the old database, insert a
new [CustInstallment] referencing to the corresponding [FinancialID]
within the new database
So if in the old database the numeric value within [Installments] is 3, then I need to INSERT INTO CustInstallments (FinancialID, InstallmentNumber) VALUES (?, ?) This ? should be 1 at the first insert, 2 and the 2nd and 3 at the 3rd. So I need some kind of a loop here? Is that even possible within the data flow of SSIS?
Below the visualization (figure) and description of my flow so far.
I select the old database source [Financial]
I convert the data so it matches the current database data types
Since I already migrated the old [Financial] database data to the new one, I can use the lookup on the FinancialID's in the new database, so the first variable ? of the INSERT query can be linked to the lookup output.
I split all the possibilities, like when the Installment contains NULL, 1, 2, 3 or 4.
The 5th step is what I'm looking for. Some clue, some direction towards something useful. When NumberOfInstallments is 1, I need to INSERT INTO CustInstallments (FinancialID, InstallmentNumber) VALUES (?, ?) with the second ? variable as 1. When the NumberOfInstallments are 2, then I need to do two inserts, one with InstallmentNumber 1, and one with InstallmentNumber 2. When NumberOfInstallmentNumber is 3, then 3 inserts with a counting NumberOfInstallmentNumber. When 4, then four.
Is there any smart way to achieve this? Is there any built-in function available of SSIS that I am not aware of, and could be used here?
I appreciate any input here!
Thank you.
EDIT 10/02/2014
I have tried the following code:
INSERT INTO CustInstallments (FinancialID, InstallmentNumber) values (?, X);
WITH nums AS(select top 4 row_number() over (order by (select 1)) AS id
from sys.columns
) SELECT f.* FROM CustInstallments f
JOIN nums n on f.InstallmentNumber>= n.id
But this query doesn't create X-amount of records, instead, the JOIN nums just replicates it X-amount of times, so I still can't track every installment individually.
I have written my own code - toke me a while since I never worked with TSQL before - and this works like a charm in SQL Server:
DECLARE #MyCounter tinyint;
SET #MyCounter = 1;
WHILE (SELECT COUNT(*) FROM CustInstallments WHERE FinancialID = #ID) < 4
BEGIN
INSERT INTO CustInstallments (FinancialID, InstallmentNumber) VALUES (#ID, #MyCounter)
IF (SELECT COUNT(*) FROM CustInstallments) > 4
BREAK
ELSE
SET #MyCounter = #MyCounter +1;
CONTINUE
END
Now in SSIS, I cannot change the #ID to a ?-variable, and use the lookup FinancialID, because as soon as I do, I get the following error:
Could anyone explain me why SSIS doesn't like this?
EDIT 10/02/2014
My last and least preferable option would be to use multicast to cast an insert query X amount of times, where each X is an OLE DB Command. For example, when there are 3 [Installments] in the old column, I would create a multicast with 3 OLE DB commands, with their SqlCommand:
OLE DB Command 1: INSERT INTO CustInstallments (FinancialID, InstallmentNumber) values (?, 1);
OLE DB Command 2: INSERT INTO CustInstallments (FinancialID, InstallmentNumber) values (?, 2);
OLE DB Command 3: INSERT INTO CustInstallments (FinancialID, InstallmentNumber) values (?, 3);
This is an ugly approach, but with the small amount of data I am using, perhaps it's not a big deal.
I would try to resolve this with TSQL in your source query. Do a join to some kind of numbers table like this:
create table #fininancial (id int not null identity(1,1), investments int);
go
insert into #fininancial (investments) values (1),(2);
GO
with nums as (select top 5 row_number() over (order by (select 1)) as id
from sys.columns
)
select f.* from #fininancial f
JOIN nums n on f.investments >= n.id
EDIT:
The above example is unclear - sorry about that. I was only presenting the concept of replicating the rows, but not completing the thought of how you will apply it. Try this out:
create table #fininancial (financialid int not null, investments int);
go
insert into #fininancial (financialid, investments) values (123, 1),(456, 2);
GO
with nums as (select top 5 row_number() over (order by (select 1)) as id
from sys.columns
)
select f.financialid, n.id as investments from #fininancial f
JOIN nums n on n.id <= f.investments
So for each financialid you will get multiple investments with different investment ids. This is a set-based way to handle the operation, which will perform better than a procedural method and will require less effort in ssis. Does that make more sense?

Microsoft SQL Server Management Studio is there a Query name header like feature?

So linqpad allows you to name queries so that when you run the query it comes up as a header to the query itself when you click run- this helps when you have multiple selects going on at the same time: is there a similar feature on MSQL mgmt studio?
so, I.E. when queried, rather than
Query1Table1|Query1Table2|Query1Table3
Query2Table1|Query2Table2|Query2Table3
Query3Table1|Query3Table2|Query3Table3
you could see
'People'
Query1Table1|Query1Table2|Query1Table3
'Students'
Query2Table1|Query2Table2|Query2Table3
'class'
Query3Table1|Query3Table2|Query3Table3
Not that I've seen. If you're looking for the ability to add some verbose/debugging values to your results, you could do a one-off select before your actual select. You can wrap these statements in an If #debug check so you can selectively turn them on/off easily. I do this for some of our more complicated queries to help with debugging, especially when there are table variables used. As a simple example:
declare #debug bit;set #debug=1;
declare #t table (id int)
insert into #t select 1
insert into #t select 2
insert into #t select 3
insert into #t select 4
insert into #t select 5
-- Debugging
if (#debug=1) begin
select '#T contents:';
select * from #t
end
-- Actual select
select * from #t where id >3;

How to compare multiple parameters of a row column value?

how to write query for following request?
my table:
id designation
1 developer,tester,projectlead
1 developer
1 techlead
if id=1,designation="'developer'"
Then need to first,second records.Because 2 rows are having venkat.
if id=1,designation="'developer','techlead'" then need to get 3 records as result.
i wrote one service for inserting records to that table .so that i am maintaining one table to store all designation with same column with comas.
By using service if user pass id=1 designation="'developer','techlead'" then need to pull the above 3 records.so that i am maintaining only one table to save all designations
SP:
ALTER PROCEDURE [dbo].[usp_GetDevices]
#id INT,
#designation NVARCHAR (MAX)
AS
BEGIN
declare #idsplat varchar(MAX)
set #idsplat = #UserIds
create table #u1 (id1 varchar(MAX))
set #idsplat = 'insert #u1 select ' + replace(#idsplat, ',', ' union select ')
exec(#idsplat)
Select
id FROM dbo.DevicesList WHERE id=#id AND designation IN (select id1 from #u1)
END
You need to use the boolean operators AND and OR in conjunction with LIKE:
IF empid = 1 AND (empname LIKE '%venkat%' OR empname LIKE '%vasu%')
The above example will return all rows with empid equals 1 and empname containing venkat or vasu.
Apparently you need to create that query based on the input from user, this is just an example of how the finally query should look like.
Edit: Trying to do this within SqlServer can be quite hard so you should really change your approach on how you call the stored procedure. If you can't do this then you could try and split your designation parameter on , (the answers to this question show several ways of how to do this) and insert the values into a temporary table. Then you can JOIN on this temporary table with LIKE as described in this article.

How do I check condition while mapping in SSIS?

i want to create one ssis package which takes values from flat file and insert it into database table depending upon there companyname.
for example:
I have table fields:
Date SecurityId SecurityType EntryPrice Price CompanyName
2011-08-31 5033048 Bond 1.05 NULL ABC Corp
now i want to insert Price into this table but i need to match with CompanyName
and in that also in file CompanyName is like ABC so how can i checked that and insert only particular data...
like this i have 20 records in my file with different company names.
I DID LIKE THIS
in lookup i did
and now my problem is i need to check company name from flat file and insert that company price into table but in flat file company name is given like 'AK STL' ans in table it is like 'AK STEEL CORPORATION' so for this i have used column transformation but what expression i write to find match ...same with other company names only 1ft 2-3 charachters are there in flat file please help
Basically, you are looking to "Upsert" your data into the database. Here is a simple look up upsert example. With as few of records in your dataset as you have said, this method will suffice. With larger datasets, you probably want to look into using temp tables and using sql logic similar to this:
--Insert Portion
INSERT INTO FinalTable
( Colums )
SELECT T.TempColumns
FROM TempTable T
WHERE
(
SELECT 'Bam'
FROM FinalTable F
WHERE F.Key(s) = T.Key(s)
) IS NULL
--Update Portion
UPDATE FinalTable
SET NonKeyColumn(s) = T.TempNonKeyColumn(s)
FROM TempTable T
WHERE FinalTable.Key(s) = T.Key(s)
AND CHECKSUM(FinalTable.NonKeyColumn(s)) <> CHECKSUM(T.NonKeyColumn(s))