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
Related
We have a company website where BI reports are hosted. For one particular report (and possibly for others, if this can be made to work), there is a requirement to:
a) retrieve saved values for report parameters
and
b) to save any changed values for report parameters
I know that parameter values can be retrieved from data by setting the Default Values to "Get values from a query".
However, what I would like to do is when the user presses View Report that the values that [s]he has selected should be saved to a database so that these will then form the default values for the next user.
Can this be done? There doesn't seem to be any way "out of the box".
This is quite simple.
Lets assume you had a table of Countries that drive your parameter's available values and that this table myCountryTable has two columns CountryID and CountryName.
You available values dataset would be something simple like
SELECT * FROM myCountryTable
CountryID would be the parameter value and CountryName would be the parameter label.
OK so you will have probably done all the above already.
Now, in your main dataset query simply add an INSERT statement before you main query runs.
So, if you dataset query looks like this..
SELECT * FROM SomeBigTable WHERE CountryID in (#CountryID)
you would change it to something like
INSERT INTO myLogTable
SELECT CountryID, CountryName FROM myCountryTable WHERE CountryID IN (#CountryID)
-- original query follows
SELECT * FROM SomeBigTable WHERE CountryID in (#CountryID)
Note: If you cannot change your main dataset query for whatever reason, you can do this in a separate dataset but there are a few things you will have to do
First: Change the sql so that it returns a value at the end, anything will do e.g.
INSERT INTO myLogTable
SELECT CountryID, CountryName FROM myCountryTable WHERE CountryID IN (#CountryID)
SELECT 1 as myReturnValue
Second: You must bind this dataset to something on the report such as a table or list, this is to make sure the query only executes when the report is executed, not when parameters are changed.
You could store parameters and their values every time the report is executed.
Note: Some of these integrated SQL functions maybe do not exist on your server, which depends on the server version. If that is the case, it is easy to find alternative, or even create your own function.
For example, at the end of every stored procedure that is used by report place this part of SQL query that uses newly created table dbo.ReportParameterValuePairs:
INSERT INTO dbo.ReportParameterValuePairs
(ReportName, ParameterValuePair, ExecutionDateTime)
VALUES(
'MyReport',
'$$$parameter1$$$: ' + #parameter1 + ',' +
'$$$parameter2$$$: ' + #parameter2,
GETDATE())
Later on will be clear why are these data stored and why in this way.
Nest step would be creating procedure which will retrieve value of some parameter during the last execution of report:
CREATE PROCEDURE spRetrieveReportParameterValue
#parameter NVARCHAR(100),
#report NVARCHAR(100)
AS
BEGIN
-- this is an example
DECLARE #parameters NVARCHAR(MAX) = '$$$parameter1$$$: value1, $$$parameter2$$$: value2'
-- in reality parameter-value pairs will be retrieved from database
--DECLARE #parameters NVARCHAR(MAX) =
-- (SELECT TOP 1 ParameterValuePair
-- FROM dbo.ReportParameterValuePairs
-- WHERE ReportName = #report
-- ORDER BY ExecutionDateTime DESC)
--SELECT #parameters
DECLARE #parameterValuePair NVARCHAR(200) =
(SELECT * FROM STRING_SPLIT (#parameters, ',')
WHERE
VALUE LIKE '%$$$' + #parameter + '$$$%')
--SELECT #parameterValuePair
DECLARE #value NVARCHAR(100) =
(SELECT * FROM STRING_SPLIT (#parameterValuePair, ':') WHERE value NOT LIKE '%$$$%')
SELECT TRIM(#value) AS ParameterValue
END
Parameters of the procedure are: parameter which value is needed, report that is executing.
Parameter-value pairs are stored in a single string. To access that data search table dbo.ReportParameterValuePairs for currently executing report. Order data by date and time of execution, starting from the latest.
Parameter-value pairs string will be split using ,. The result of this split is a table that consists of parameter-value pairs. Distinction between parameters and their values is $$$ mark. Because of that the condition in query is VALUE LIKE '%$$$' + #parameter + '$$$%'.
Variable #parameterValuePair now stores desired parameter and its value.
After another one split, this time using : because it separates value from parameter name, the result of split will be two rows. One contains parameter and $$$ marks ($$$[parameter]$$$) and the other contains the value. Using condition WHERE value NOT LIKE '%$$$%' parameter's value will be stored to #value variable.
Last step of the procedure is to trim the value in case there are empty spaces at the end and at the beginning of the #value and return it as ParameterValue.
In order to retrieve this value to report create DataSet for every report parameter. This DataSet will supply parameter with default value:
right click on DataSets
choose Add Dataset
choose tab/card Query
name DataSet
select Data source
for query type choose Text
enter spRetrieveReportParameterValue 'parameter1', 'MyReport' where parameter1 is name of parameter which last value will be retrieved
click Refresh Fields
The last step is to set default value to the parameter:
right click on parameter
select Parameter Properties
choose card/tab Default Values
choose option Get values from a query
for Dataset choose newly created dataset
for Value field choose ParameterValue
This should be the result:
I need, through an SQL query, to wrap the field in a table row as follows:
field: my-long-text
field after update: [:en]my-long-text[:]
how can I move?
An UPDATE query and a CONCAT should be enough:
update tablename
set
field = concat('[:en]', field, '[:]')
If field is null concat will return null, but you can exclude with where field is not null and of course if the field is already wrapped you have to exclude it somehow (but this depends on your logic).
I'm trying to update a field of my table with the CONCAT of the some fields of the same table.
Whith this
UPDATE tabex SET field1=CONCAT(tabex.a1,', ',tabex.a2,', ',tabex.a3,', ',tabex.a4,', ',tabex.a5,', ',tabex.a6,', 'tabex.a7,', ',tabex.a8,', ',tabex.a9 );
This query has 0 rows affected and no errors.
With this other query
UPDATE tabex SET field1=CONCAT_WS(tabex.a1,', ',tabex.a2,', ',tabex.a3,', ',tabex.a4,', ',tabex.a5,', ',tabex.a6,', 'tabex.a7,', ',tabex.a8,', ',tabex.a9 );
If the content of some of a(n) fields is NULL mysql puts a copy of the previous result
Someone can help me?
When this query
UPDATE tabex SET field1=CONCAT(tabex.a1,', ',tabex.a2,', ',tabex.a3,', ',tabex.a4,', ',tabex.a5,', ',tabex.a6,', 'tabex.a7,', ',tabex.a8,', ',tabex.a9 );
doesn't affect a row, the only explanation would be, that the table is empty. It would update every row in the table. But if one of the columns is NULL, your field1 column will also be NULL.
To avoid that, you have to use the COALESCE() function. This function returns the first of its parameters which is not NULL.
UPDATE tabex SET field1=CONCAT(COALESCE(tabex.a1, ''),', ',...);
On a sidenote I have to ask, why you want to do this. Comma separated values in columns are a bad idea most of the times.
And finally, your query using CONCAT_WS() is wrong. The _WS in the function name is short for "with separator", so the first parameter is the separator which then is placed between the other parameters of the function. So you should write it like this:
UPDATE tabex SET field1=CONCAT_WS(',', tabex.a1, tabex.a2, tabex.a3,...);
Another advantage of the CONCAT_WS() function is, that it ignores NULL values. Read more about the two functions in the manual.
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.
I have a table and I have added a new column to it. I need to populate this new column and also set the default value for it.
The value of the new col is obtained by concatenating two strings based on the values of other columns:
the first string is the sum COL_1 + 10000
the second string is a obtained by stripping everything but the alphanumerics in COL_2
Update TABLE set NEW_COL = CONCAT ((SUM (10000 + COL_1)), (preg_replace('/[\s\W]+/','',COL_2)))
This will be the default value for the column
The reason your update is failing is that preg_replace() is not a valid MySQL function. That's a PHP function. Here's a relevant question that addresses that functionality in MySQL:
How to do a regular expression replace in MySQL?