I have a stored procedure that returns three columns worth of data to our SSRS report. The stored procedure does not alias two of those columns, so they are returned unnamed. Here is an example of what the return dataset might look like:
[FundName] [blank] [blank]
Abc col2val1 col3val1
Def col2val2 col3val2
Ghi col2val3 col3val3
I'd like to be able to use an expression in SSRS to retrieve the values from column 2 and 3. Here's an example of what retrieving data from FundName would look like:
=Fields!FundName.Value
Is there any way to replace the column name (in this example, FundName) with say, the index or position of the column, like so:
=Fields![0].Value //returns FundName values
=Fields![1].Value //returns column 2 values
=Fields![2].Value //returns column 3 values
Thank you in advance.
If your stored procedure is not returning the columns names then you can't create a dataset in SSRS as it will throw an error
An item with the same key is already been added
and there is now way you can reference the column name using index in SSRS
Fortunately, a way to accomplish this has been found. Since our stored procedure could not be changed and it did not return enough information for SSRS to generate a report (missing column names in the resulting DataSet), we changed the way our DataSet gets populated.
In the DataSet query builder, we created a temporary table and had the stored procedure insert into that temporary table. Once inserted, we selected all the values in our temporary table which populated the DataSet. Now the DataSet has 3 columns with 3 column names to be used by our report.
CREATE TABLE #tempTable (
FundName varchar(50),
col2 dec(15,4),
col3 char(8)
)
insert into #tempTable
exec storedProcedureName
select * from #tempTable
drop table #tempTable
Then you can access those column values in an expression just like before:
=Fields!FundName.Value //returns FundName values
=Fields!col2.Value //returns column 2 values
=Fields!col3.Value //returns column 3 values
I hope this helps anyone else with this particular issue.
Related
So I have a base table - TRAINING, which has 100 columns. Some of the columns will be completely NULL and some will contain Values. So say COLUMN 1-20 are null and COLUMN 21-100 are not NULL.
I have another table called - CONFIGURATION. It has only one column of type VARCHAR. This table contains the name of those columns from the TRAINING table that are not NULL. So it'll contain values - COLUMN 21-100.
What I want to do is- fetch the data of only those columns that are not NULL. So I want the output as the data points contained in table COLUMN 21-100. This number may be different every time and it can also be interleaved, say COLUMN 1-10 is NULL and COLUMN 11-25 not NULL and the remaining again NULL.
I am thinking of implementing inner Join but I do not have the table structure required for it.
Please provide some hint.
Thanks.
You need to create dynamic SQL for that.
First step - create ALL_COLUMNS variable of VARCHAR(5000) data type.
From your CONFIGURATION table select column names which you want to query. Then use STRING_AGG function to aggregate them into single value (in my example COL1 is column from CONFIGURATION table). Assign output to the ALL_COLUMNS variable
Second step use EXECUTE IMMEDIATE to run dynamic SQL. Add ALL_COLUMNS variable as input for that query.
Here is the examplary code:
DO
BEGIN
/* First Step - create string with all column names separated by comma*/
DECLARE ALL_COLUMNS VARCHAR(5000);
SELECT STRING_AGG(COL1,',' ORDER BY COL1) INTO ALL_COLUMNS FROM CONFIGURATION;
/*Second Step - create dynamic SQL including variable from First Step*/
EXECUTE IMMEDIATE ('SELECT ' || :ALL_COLUMNS || ' FROM "TRAINING" ');
END
I am able to execute my stored procedure. When I execute it a second time instead of updating the existing values same values from source are inserted as new values.
i.e my target has
1
2
3
When I run the stored procedure a second time, instead of updating 1,2,3, it is inserting the same
1
2
3
1
2
3
My condition for when matched then select S.REPORT_TEST1 except T.REPORT_TEST1 is not working.
When I use the same code on a different table which doesn't have data conversions I am able to update.
Can anyone tell where am I going wrong?
CREATE PROCEDURE [dbo].[Merge]
INSERT INTO .[dbo].[TARGET](REPORT_TEST1, REPORT_TEST2, REPOST_TEST3)
FROM (MERGE [dbo].[TARGET] T
USING (SELECT
Cast([REPORT TEST1] as int) [REPORT_TEST1],
Cast([REPORT TEST2] as int) [REPORT_TEST2],
Cast([REPORT TEST3] as int) [REPORT_TEST3]
FROM
[dbo].[SOURCE]) S ON (T.[REPORT_TEST1] = S.[REPORT_TEST1])
WHEN NOT MATCHED BY TARGET
THEN INSERT
VALUES (S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3)
WHEN MATCHED
AND EXISTS (SELECT S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3
EXCEPT
SELECT T.REPORT_TEST1, T.REPORT_TEST2, T.REPOST_TEST3)
OUTPUT $ACTION ACTION_OUT,
S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3) ;
Thanks
would it not suffice to rewrite your WHEN MATCHED statement thusly:
WHEN MATCHED
AND S.REPORT_TEST2 <> T.REPORT_TEST2
AND S.REPORT_TEST3 <> T.REPORT_TEST3
(
SELECT
S.REPORT_TEST1
,S.REPORT_TEST2
,S.REPOST_TEST3
)
I think I understand what you're trying to do, but inside the MERGE context, you're only comparing this row with that row, not the source row against the whole target table. you could modify the subselect thusly if you're trying to query "this source is not at all in the target"
WHEN MATCHED AND EXISTS
(
SELECT
S.REPORT_TEST1
,S.REPORT_TEST2
,S.REPOST_TEST3
EXCEPT SELECT
T2.REPORT_TEST1
,T2.REPORT_TEST2
,T2.REPOST_TEST3
FROM
[dbo].[TARGET] T2
)
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.
Need assistance on the following. How can I copy data from one SQL column table to another sql column table?
I have the following tables
dbo.Thecat62 and dbo.thecase6
inside dbo.Thecat62 , I need to copy the column Work_Order_Job_Start_Date values to dbo.thecase6 column Job_Start_Date. Currently there are null value in the Job_Start_Date column in dbo.thecase6.
I have tried using the following command
INSERT INTO dbo.thecase6 (Job_Start_Date)
SELECT Work_Order_Job_Start_Date
FROM dbo.thecat62
but received the error Cannot insert the value NULL into column 'CaseNo', table 'Therefore.dbo.TheCase6'; column does not allow nulls. INSERT fails.
The statement has been terminated.
Any help will be great!
Thanks!
Because on this table Therefore.dbo.TheCase6 for CaseNo you have specify Not NULL Constraints
something like this
CaseNo int NOT NULL
But you did not select the CaseNo column from the dbo.thecat62 table, so you are explicitly trying to insert nulls into a non-nullable column.
You just need to select the CaseNo column, as well, presuming it does not contain any nulls in teh source table.
INSERT INTO dbo.thecase6 (Job_Start_Date,CaseNo)
SELECT Work_Order_Job_Start_Date,CaseNo FROM dbo.thecat62
The error says it has a column CaseNo which doesn't allow NULL.
Cannot insert the value NULL into column 'CaseNo', table 'Therefore.dbo.TheCase6';
You are inserting rows in the new table which will have just 1 column filled and rest of the columns will be empty
Either
Alter the table in which you are inserting the data and allow the column to allow null values.
Or
if you don't want to allow null values, update the null values to some default values.
I have a simple stored procedure that is pulling data for a SS report. One of the columns uses only a letter for the value. I would like to spell out the word the letter represents for the report. The procedure looks something like this...
ALTER PROCEDURE RPT_MYREPORT
{
#PID INT=1234567
}
AS BEGIN
SELECT
SSN,
DOB,
PID,
Name,
MaritalStatus
FROM
Customers
END
Obviously theres more to it but thats the basic setup. Marital Status is either an "S" for Single or "M" for Married. I would like to have these values spelled out for my report. Anyone know how?
Add a lookup table to your database containing the letter and the name/description you want to display. Join your main table to this in the query supplying the data to the report.
E.g. for the lookup table:
CREATE TABLE Marital_Status (
marital_status_code char(1) PRIMARY KEY,
marital_status_name char(7)
)
then add the lookup data
INSERT Marital_Status(marital_status_code, marital_status_name)
VALUES ('S', 'Single')
INSERT Marital_Status(marital_status_code, marital_status_name)
VALUES ('M', 'Married')
If you set the relationship between the main and lookup tables it also serves as data validation when new rows are inserted.
You have 2 options:
Convert value to word inside SP (case MaritalStatus when 'S' then 'Single' when 'M' then 'Married' for example)
Convert value to word inside report definition (expression based on iif function)