I am using Webi to create reports but instead of using universes I would like to use custom SQL queries since I already have stored procedures created. In the stored procedures I have parameters like #date and #id. Is there a way to use them in Webi custom SQL scripts?
An example is:
SELECT
Client,
TradeSize
FROM
table1
WHERE Date = #Date
AND id = #ID
Related
I am dealing with a specific problem of identifying the dependent db objects for any SSRS RDL.
I have a good understanding of if any dataset have stored procedure as the query in a RDL then I can reference the associated stored procedure and get all the dependent objects (details can be found here: Different Ways to Find SQL Server Object Dependencies)
But I am looking specifically for the datasets with text query or inline query for any rdl. I am able to extract the CommandText from the XML of the rdl but I am not sure how to extract db objects like sp, table, views columns form a command text which is inline query in the rdl.
For example if I extract below query from XML commandText (this is a hypothetical query, names are not standardized in the database like vw_ for views , udf_ for functions):
-----This query serves Report ABC
SELECT DATE
,[amount]
,teamID = (SELECT TeamID FROM Sales.[getSalesPerson](r.date) as s WHERE R.[SalesPersonName] = S.[SalesPersonName])
,[channel]
,[product]
,[Item]
,r.[M_ID]
,Amount
,M.[Type]
FROM dbo.FactTable AS R
LEFT JOIN sp_Channel C ON R.[Channel_ID] = C.[Channel_ID]
LEFT JOIN Marketing.vw_M M ON R.[M_ID] = M.[M_ID]
Is there a way to identify that this query have dependent object as below:
ObjectName ObjectType
------------------------------------------
dbo.FactTable Table
sp_Channel Stored Procedure
Marketing.vw_M View
Sales.[getSalesPerson] Function
It is not easy to extract object names from an SQL command since they may be written in different ways (with/without schemas, databases name included ...)
But there are many option to extract objects from an SQL query that you can try:
Using Regular expressions, As example: You have to search for the words located after the following keywords:
TRUNCATE TABLE
FROM
UPDATE
JOIN
The following code is a C# example:
Regex regex = new Regex(#"\bJOIN\s+(?<Retrieve>[a-zA-Z\._\d\[\]]+)\b|\bFROM\s+(?<Retrieve>[a-zA-Z\._\d\[\]]+)\b|\bUPDATE\s+(?<Update>[a-zA-Z\._\d]+)\b|\bINSERT\s+(?:\bINTO\b)?\s+(?<Insert>[a-zA-Z\._\d]+)\b|\bTRUNCATE\s+TABLE\s+(?<Delete>[a-zA-Z\._\d]+)\b|\bDELETE\s+(?:\bFROM\b)?\s+(?<Delete>[a-zA-Z\._\d]+)\b");
var obj = regex.Matches(sql);
foreach(Match m in obj)
{
Console.WriteLine(m.ToString().Substring(m.ToString().IndexOf(" ")).Trim());
}
Output
Then you have to clean and join the result with the sys.objects tables from the SQL Server database.
Using a SQL parser, as example:
SQL Parser
SQL Parser - Code Project
You can refer to the following very helpful links for additional information:
Regular expression to find all table names in a query
Parsing SQL code in C#
If your reports are connecting to SQLServer and you have access you could try to get the execution plan with SET SHOWPLAN_XML ON and parse it.
Relevant thread for the parsing:extracting-data-from-sql-servers-xml-execution-plan
I have a problem in Crystal reports 11. Because it has limitation to showing the information in dynamic reports and I have a huge list of customer, I want to write a query and ask the first letter of the customer name. If for example, it starts with A, just show the A customers.
this is my query:
select distinct bill_to_code
from TLORDER
where left(BILL_TO_CODE ,1 ) = ?
And CURRENT_STATUS <> 'CANCL'
AND LEFT(BILL_NUMBER , 1 ) NOT IN ('M','U','T','K')
but when I copy this to crystal reports and create a parameter , I get an error
Failed to retrieve data from the database
I should mention that I have another sql query in this report .
It is best to use Stored Procedure when trying to pass a parameter. How to create SP. Then used the SP for your report.
I am trying to query bamboo's database to get the following information. I want to find out the trigger information, which is what environment is triggered by which branch on which build plan. The problem is that some environments can be triggered by other environments.
So far I have looked up the Bamboo database and I seem to have most if not all the information that I need. What I have done is there is a table in the Bamboo database called dbo.Deployment_Environment which has the fields, EnvironmentID and Triggers_XML_Data which is exactly what I need from it. Then there is another table called the dbo.Deployment_Result which has the EnvironmentID, Deployment_State and the Trigger_Reason.
From these two tables what I think I need to do is this. select all these columns but if the trigger_reason contains environment and also if the triggers_xml_data contains environment, then get that environment from the triggers_xml_Data (this is under the xml node /item/value). Once you get that ID select all the same columns until and repeat the process if environment is the reason for deployment again until it is not. The triggers_xml_data data type is ntext and the trigger_reason is nvarchar.
I am not exactly sure how I can do this in SQL this is what I am trying so far but I can't get the right information:
alter proc dbo.myStoredProc3
as
Declare #EnvironmentID int
select
#EnvironmentID as ENVIRONMENT_ID,
de.ENVIRONMENT_ID, dr.DEPLOYMENT_STATE,
de.TRIGGERS_XML_DATA, dr.TRIGGER_REASON, de.NAME
from
dbo.BUILDRESULTSUMMARY as br,
dbo.DEPLOYMENT_ENVIRONMENT as de,
dbo.DEPLOYMENT_RESULT as dr
where
dr.TRIGGER_REASON like '%environment%'
(
select de2.ENVIRONMENT_ID as 'test'
from dbo.DEPLOYMENT_ENVIRONMENT as de2
)
I know this is not going to get the right information but every time I tried to do case's or if statements in the SQL it would create an error too: How can I do this query correctly? I think that I all the information I need but if not I can add more.
I have also tried to do the following:
While (#Counter <= 5)
Begin
Select de.NAME As 'Deployment Name', dr.TRIGGER_REASON as 'Trigger Reason', dr.DEPLOYMENT_STATE as 'Status'
from dbo.DEPLOYMENT_ENVIRONMENT as de, dbo.DEPLOYMENT_RESULT as dr
Where de.TRIGGERS_XML_DATA like '%environment%' and dr.TRIGGER_REASON like '%environment%'
SET #Counter = #Counter + 1
END
But this will not link the columns that I am getting. If the Trigger_Reason is to do with the environment then in the ntext the it will have a node that has the environmentID, I want to get this and set it as a variable, which I can use to get further columns that link to together e.g. Select name from dbo.Environment where #NewEnvironmentID = de.EnvironmentID.
Edit
Using the following SQL query:
alter proc getEnvironmentTriggers
#EnvironmentID int
as
Select a.NAME, a.TRIGGERS_XML_DATA, a.TRIGGER_REASON, a.ENVIRONMENT_ID
From (Select de.NAME, de.TRIGGERS_XML_DATA, de.ENVIRONMENT_ID, dr.TRIGGER_REASON From dbo.DEPLOYMENT_ENVIRONMENT as de
Inner join dbo.DEPLOYMENT_RESULT as dr
on dr.ENVIRONMENT_ID = de.ENVIRONMENT_ID
Where #EnvironmentID = de.ENVIRONMENT_ID and de.TRIGGERS_XML_DATA like '%Environment%' and dr.TRIGGER_REASON like '%Environment%' ) a
I am getting close to what I need. Doing this and the executing the Stored procedure like this: exec dbo.getEnvironmentTriggers 15892483, this will return in the query inside the ntext l of the TRIGGERS_XML_DATA, will have a value of 18317322, and then using that ID I can get the value of 19234819, that is then the last environment that triggers all of my environments from that ID.
So what I am trying to do is this:
In an automated way get all of these ID's possibly by doing the following.
Exec the stored procedure using all of the ID's (maybe using some sort of for each way).
Search the ntext column in the SQL to get the environment ID (this is in the following node /item/value.
Store that as a variable, then use it to get all the columns from the other stored procedure.
If there is returned columns using the stored procedure, run the procedure again, if not export all of the TRIGGER_XML_DATA columns that were got from stored procedures.
Is there a way that I can do this?
See my answer here - https://answers.atlassian.com/questions/44908050/how-to-get-the-trigger-information-from-the-bamboo-database
Not sure it's possible to do with plain SQL
What about using Bamboo REST API
http://bamboo_host/rest/api/latest/plan.json?expand=plans.plan.actions
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Parameterizing an SQL IN clause?
Every now and then I work on a system that allows the user to select multiple items and then perform a bulk action on them. Typically, I resorted to building the SQL at runtime, something like this:
string inClause = String.Join(", ", selectedIds);
string command = "SELECT * FROM Customer WHERE CustomerId IN ({0})";
command = String.Format(command, inClause);
Of course, this style of code is insecure because of SQL injection. I could solve that by putting in parameter placeholders and creating parameters.
Still, I am wondering if there is another approach that I've just not considered. I certainly don't want to execute the command once for each ID.
There are two good approaches:
Build the string with command placeholders (like you said)
Join to the values of a TVP
Burning the IDs into the SQL is not good because it prevents plan caching and opens the potential for injection.
You can build an XML string and then pass it to a stored proc. Executing it would look like:
EXECUTE getLocationTypes '<IDList><ID>1</ID><ID>3</ID></IDList>'
The stored proc would look something like:
create proc [dbo].[getLocationTypes](#locationIds XML)
as
begin
set nocount on
SELECT locationId, typeId
FROM xrefLocationTypes
WHERE locationId
IN (SELECT Item.value('.', 'int' )
FROM #locationIDs.nodes('IDList/ID') AS x(Item))
ORDER BY 1, 2
end
Notice the data type of the parameter is XML. This is a little more complicated than what you are doing, guess you could do it all in a single SQL string.
I have a stored procedure that returns two selects, which I use in a report.
The first select is data to display in tabular format and the second are metadata to display in the report head, like showed below:
CREATE PROCEDURE dbo. GetReport
#Input INT
AS
BEGIN
--Get #Metadata
-- #Results = f(#Metadata) … compex calculation
SELECT * FROM #Results
SELECT * FROM #Metadata
END
As the sproc calculation is quite intensive, I would like to prepare the report lines as plain data (in two tables: PrecalcResults and PrecalcMetadata) for some mostly used sproc parameters overnight.
Lather I would directly select the precalculated vaues or calculate them with the sproc according to the parameters.
For maintenance reasons I would like to use the same sproc to calculate data that would be:
1. showed in the report
2. be stored in PrecalcResults and PrecalcMetadata (with the used parameters)
If I would have single select sproc I would an approach desctibed here:
Insert results of a stored procedure into a temporary table
As I have multiselect sproc I would like to do something like above but with two tables.
In .net I would do DataSet.Tables[0] and DataSet.Tables[1]..., but I want to do it in tsql, to run it in daily job.
Is this even possible in MS SQL?
I have to apologize myself, from the answer below I can see I was not very clear.
I would like to do implement this functionality as pure TSQL.
Yes, this is possible.
It's perfectly fine to return multiple result sets from a single stored procedure as you have suggested.
Your only potential issue is the limitation of a TableAdapter being able to pull both result sets from the stored procedure, but there's a very simple work-around for that issue.