Forum Discussion
Use SQL Store Procedure in Power BI
vineetmodiZak2815anakoom Letting the cat out of the bag a little early here as I'm going to write up a blog around this, but rather than use a stored procedure you can use a Table Valued Function. This function allows for input parameters to be passed in. For example: if I were to query the AdventureWorks2014 database and a function in there looks like this:
CREATE FUNCTION [dbo].[ufnGetContactInformation](@PersonID int)
RETURNS @retContactInformation TABLE
(
-- Columns returned by the function
[PersonID] int NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[JobTitle] [nvarchar](50) NULL,
[BusinessEntityType] [nvarchar](50) NULL
)
AS
-- Returns the first name, last name, job title and business entity type for the specified contact.
-- Since a contact can serve multiple roles, more than one row may be returned.
BEGIN
IF @PersonID IS NOT NULL
BEGIN
IF EXISTS(SELECT * FROM [HumanResources].[Employee] e
WHERE e.[BusinessEntityID] = @PersonID)
INSERT INTO @retContactInformation
SELECT @PersonID, p.FirstName, p.LastName, e.[JobTitle], 'Employee'
FROM [HumanResources].[Employee] AS e
INNER JOIN [Person].[Person] p
ON p.[BusinessEntityID] = e.[BusinessEntityID]
WHERE e.[BusinessEntityID] = @PersonID;
IF EXISTS(SELECT * FROM [Purchasing].[Vendor] AS v
INNER JOIN [Person].[BusinessEntityContact] bec
ON bec.[BusinessEntityID] = v.[BusinessEntityID]
WHERE bec.[PersonID] = @PersonID)
INSERT INTO @retContactInformation
SELECT @PersonID, p.FirstName, p.LastName, ct.[Name], 'Vendor Contact'
FROM [Purchasing].[Vendor] AS v
INNER JOIN [Person].[BusinessEntityContact] bec
ON bec.[BusinessEntityID] = v.[BusinessEntityID]
INNER JOIN [Person].ContactType ct
ON ct.[ContactTypeID] = bec.[ContactTypeID]
INNER JOIN [Person].[Person] p
ON p.[BusinessEntityID] = bec.[PersonID]
WHERE bec.[PersonID] = @PersonID;
IF EXISTS(SELECT * FROM [Sales].[Store] AS s
INNER JOIN [Person].[BusinessEntityContact] bec
ON bec.[BusinessEntityID] = s.[BusinessEntityID]
WHERE bec.[PersonID] = @PersonID)
INSERT INTO @retContactInformation
SELECT @PersonID, p.FirstName, p.LastName, ct.[Name], 'Store Contact'
FROM [Sales].[Store] AS s
INNER JOIN [Person].[BusinessEntityContact] bec
ON bec.[BusinessEntityID] = s.[BusinessEntityID]
INNER JOIN [Person].ContactType ct
ON ct.[ContactTypeID] = bec.[ContactTypeID]
INNER JOIN [Person].[Person] p
ON p.[BusinessEntityID] = bec.[PersonID]
WHERE bec.[PersonID] = @PersonID;
IF EXISTS(SELECT * FROM [Person].[Person] AS p
INNER JOIN [Sales].[Customer] AS c
ON c.[PersonID] = p.[BusinessEntityID]
WHERE p.[BusinessEntityID] = @PersonID AND c.[StoreID] IS NULL)
INSERT INTO @retContactInformation
SELECT @PersonID, p.FirstName, p.LastName, NULL, 'Consumer'
FROM [Person].[Person] AS p
INNER JOIN [Sales].[Customer] AS c
ON c.[PersonID] = p.[BusinessEntityID]
WHERE p.[BusinessEntityID] = @PersonID AND c.[StoreID] IS NULL;
END
RETURN;
END;
In my advanced options - SQL Query in Power BI I can call it just executing the select like this:
select * from [dbo].[ufnGetContactInformation] (73)
and the output is returned as expected. This also allows you to do any CTE's or temp tables within the function.
- Anonymous9 years agoNot applicable
anakoom You can't. If you watch what is actually sent to the SQL server you will see that an added syntax is added to the command which invalidates the statement. In Import, it just executes the SQL statement. In Direct Query it changes it to something like Select * from () - this is off the top of my head. In either case, that is why the openquery works, or the table valued function because both of those wouldn't create un-executable code.
I'm giving you an alternative to a SP because that method doesn't work, you can transform whatever you are doing in that SP to the TVP.
- anakoom9 years agoHelper IThanks ..let me convert to TVF..is there any way I can allow user to
Pass parameter value and data will fetch based on given parameter? - Anonymous9 years agoNot applicable
anakoom Probably not in the way you are thinking...
Power BI is best when you pull in the larger dataset and add slicers and filters to the report.
I'm not aware of any way to pass a parameter all the way downstream from a deployed report in the Power BI Service. You can do this in the desktop, but that would be stuck in that mode from my understanding.
- sekic9 years agoHelper I
Hi,
table value function is just fine, but not work if you call it with parameter which is not constant :(
I tried to send any info about userid, dax expresion about userid, or anything similar which is not constant, didn't successed.
select * from TableFunction('abc') run fine, but
select * from TableFunction(USERPRINCIPALNAME()) fail...