Directly query TFS Warehouse using T-sql - sql-server

Hi I'm wondering if anybody has had any experience querying a Team Foundation Server store to retrieve current work item information. It is my understanding that the information I require is stored in the TFSWarehouse Database.
I'm well aware that there are APIs that provide this functionality and I've used them myself. However these come with the requirement to install Team Explorer on any client PC that will reference the API.
All I want is a list of Work Items with some selected fields such as Title, State and Created By.
Has anybody attempted this themselves, and indeed does anybody know of any pitfalls with this approach?
---------- EDIT 16/02
Just to add after speaking with TreeUK. What would be great is if anybody perhaps has an example query, or maybe some explanation as to the table structure?

If you have access to the SQL database that hosts TFS, you can write a query that pulls this information out.
The database you want to look at is TFSWarehouse.
Below is a query that gets Work Item general information.
select System_Id as WorkItemId, System_Title as Title,
System_State as Status, System_Reason as Reason,
System_WorkItemType as Type
from [Work Item]
It's kind of clear what they all do, check that table to get any other properties of interest.

TFS 2005, it'll need to be [workitemtracking].dbo.[workitemsare]

SELECT DISTINCT Top(100) FactWorkItemLinkHistory.WorkItemLinkTypeSK, DimWorkItemLinkType.LinkName, DimWorkItem.System_Id, DimWorkItem.System_Title
FROM FactWorkItemLinkHistory
INNER JOIN DimWorkItemLinkType ON DimWorkItemLinkType.LinkID = FactWorkItemLinkHistory.WorkItemLinkTypeSK
INNER JOIN DimWorkItem ON DimWorkItem.System_Id = FactWorkItemLinkHistory.SourceWorkItemID
WHERE FactWorkItemLinkHistory.WorkItemLinkTypeSK = 2

TFS 2013, it'll need to be [Your Tfs_Warehouse database].dbo.DimWorkItem
SELECT System_Id as WorkItemId, System_Title as Title,
System_State as Status, System_Reason as Reason,
System_WorkItemType as Type
FROM dbo.DimWorkItem

Related

How can I traverse through multiple related objects based on ID and return some related field?

I'm a little stuck.
I am trying to generate a report that determines whether anyone has made a manual change to certain fields within our order framework. I have figured out the proper fields and structures to audit, and even how to make the report, but I used a combination of extracts from the Dataloader and Excel xlookups to make it. Now, I'm being asked to find a way to automate the generation of the report, and I suspect that means I need to write a SOQL query to figure it out. I'm having trouble traversing multiple relationships based on these ID fields. Essentially, what I'm trying to do is make multiple "left joins" based on the 18 digit Salesforce IDs and extract some related piece of information from those other objects.
For example, if I'm starting with order_product_history (with a field OrderProductID to identify the order product) and I want to bring in "Product Name", I have to first match OrderProductID with the ID field in my order_product "table", then I have to match the Product2ID field in my order_product "table" with the ID in my product "table", then I have to get the matching Product Name as a column in my report:
Matching/Traversal Process
Desired Result
That's one example for one field. I also have to bring in things like User Name from the users "table", and order number from the orders table, but once I get the general idea, I think I'll be OK. I also want to filter the results to only include my Fee__c and UnitPrice fields, ignore the automated users and set a date filter--not sure if I have to do that using a WHERE clause just in my main query, or if I have to filter the subqueries as well.
I am not a programmer and I have no formal Salesforce training; I am just an analyst who is technically inclined and sort of fell into the role of Salesforce Admin. I am familiar with programming concepts and have been writing things using the flow application and have even dipped my toes into some Apex stuff, but it can be a bit of a struggle. I am not asking you to do my job for me and I am willing to work at the problem and learn; any help is appreciated. Sorry about the links; SO won't let me embed images yet.
There's high chance you don't have to write any code for it. I'll give you some tips, experiment a bit and edit the question or post new one?
This diagram might help: https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_erd_products.htm
Developer way
It's all about writing the right query. You can play with it in Developer Console or Workbench for example. Read up about relationship queries in SF.
https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_relationships_understanding.htm
https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_relationships_query_hist.htm
I don't have org with orders enabled but this should be a good start:
SELECT CreatedById, Created.Name,
Parent.Name, Parent.Product2.Name, Parent.Order.Name,
Field, OldValue, NewValue, CreatedDate
FROM OrderItemHistory
If it throws errors about "Parent" see if "OrderItem" will work. Once you have it - WHERE Field IN ('UnitPrice', 'Fee__c') AND CreatedDate = LAST_WEEK might be good next step. (dates can be filtered by date but there are few "constants" that are more human-readable too)
You could even export this with Data Loader, you just have to start the wizard on Order Product history table. But you can ignore the whole query creator and paste a query you've created.
Admin way
Have you ever created a report in Salesforce? There are self-paced trainings (for Lightning and Classic UI) and tons of YouTube videos. Get a feel of making few reports.
What you want might be doable with built-in report type (see if there's new report -> order product history). If nothing exciting - as admin you can make new report type in setup. For example Orders -> Order Products -> Order Product History. Screenshots from here might help.
Just wanted to update this for anyone looking for a solution in the future.
Turns out you can traverse these as a parent-child relationship in the SOQL query. Here's the query I ended up using:
SELECT CreatedBy.Name, FORMAT(CreatedDate), OrderItem.Order.OrderNumber, OrderItem.Product2.Name, OrderItem.Product2.ProductCode, Field, OldValue, NewValue
FROM OrderItemHistory
WHERE (Field = 'Fee__c' OR UnitPrice) AND (CreatedBy.Name != 'Integration User') AND (Created Date >= 2020-11-24T00:00:00.000Z) ORDER BY CreatedDate DESC

How to translate a WIQL query into T-SQL

(Disclaimer: T-SQL and SSRS expert, about two hours exposure to WIQL)
I have some users that created a Team Foundation Services (TFS) Work Items query using the UI designer that they're in love with, with hard-coded monthly parameters, and have asked me to explore converting this into an SSRS report where they can pass all the parameters they want.
To do that I'm guessing that I'd need to convert the query into T-SQL.
Exporting the report into a .wiq file, then reading the query in the xml within the .wiq file I was able to extract the below WIQL (slightly edited for confidentiality). Problem is, looking at my TFS server, which contains databases TFS_Coniguration, Tfs_CX, Tfs_DefaultCollection, TFS_IT, and TFS_Warehouse, I don't see a table or view named WorkItems anywhere, so I'm at a loss to translate the below WIQL into T-SQL.
If there's some kind of table alias stored in TFS that would give me clues, I'm not seeing it.
So, question: How can I convert the below WIQL into T-SQL?
SELECT
[System.Id], [System.AreaPath], [System.Title], [System.Tags], [System.AssignedTo],
[System.State], [foo.VSTS.Agile.Release], [System.CreatedDate], [Microsoft.VSTS.Scheduling.StoryPoints]
FROM
WorkItems
WHERE
[System.TeamProject] = #project AND
[System.WorkItemType] IN ('User Story') AND
[System.State] = 'Active' AND
[foo.VSTS.Agile.Release] <= '2018-06-10T00:00:00.0000000' AND
[foo.VSTS.Agile.Release] >= '2018-06-30T00:00:00.0000000' AND
[System.AreaPath] UNDER 'AppDev'
ORDER BY
[foo.VSTS.Agile.Release]
Daniel is right, it's not suggest to use SQL to query TFS operational store directly(Tfs_DefaultCollection), which may lose support from MS TFS support team.
One way to do this is using the database view
vw_denorm_WorkItemCoreLatest. In this case "Latest" means, you only
get the latest revision of the workitem without any previous versions
of it. If you need all versions of a workitem, use the view
vw_WorkItemCoreAll.
The example from the WIQL looks like:
SELECT [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State]
FROM WorkItems
WHERE [System.TeamProject] = #project
and [System.WorkItemType] = 'Ticket'
and [System.State] <> 'Closed'
and [System.State] <> 'Removed'
Except the selected columns, a sample of SQL for your reference:
SELECT *
FROM [dbo].[vw_denorm_WorkItemCoreLatest]
WHERE [System.TeamProject] = 'MyTeamProject'
and [System.WorkItemType] = 'Ticket'
and [System.State] <> 'Closed'
and [System.State] <> 'Removed'
For warehouse, please take a look at How to query Work Items using SQL on the Relational Warehouse
I took a different approach. I have used a SSIS package to call the data to an Excel file and build a Data Mart out of it which supports Incremental Load. Then I am using an SSRS to easily use the data within my SQl table to build my report

SQL Server : reverse engineering view and stored procedure

I need some help from your side.
For example I have a SQL Server view MyView.
Adb.vs.MyView
with columns:
ID
Name
Address
Email
Phone
Logic behind the view is next
SELECT
Ac.AccountID AS ID,
Ac.AccountName AS Name,
Ad.Main_Adress AS Address,
Em.Main_Email AS Email,
Concat(Ph.Phone_Area_Code,Ph.Mobile_Phone_Number) AS Phone
FROM
Bdb.dbo.Account AS Ac
INNER JOIN
Cdb.dbo.Address AS Ad ON Ac.AccountID = Ad.AccountID
INNER JOIN
Cdb.dbo.Emails AS Em ON Ac.AccountID = Em.AccountID
INNER JOIN
Cdb.dbo.PhoneBook AS Ph ON Ac.AccountID = Ph.AccountID
NOTE:
No KEY relations build between all this tables.
My target to reverse engineer this view to get next kind of result:
Please suggest any kind of tool/tools or scripts to perform this.
Also, if somebody know similar solution but for Rev.En. stored procedures which was used to populating data into tables I will be really appreciated
bec. I will need to reverse tons of such kind views and stored procedures in nearest future.
Thanks in advance for any kind of support !
Take a look at the system views. Most of what you want is probably available in INFORMATION_SCHEMA.VIEW_COLUMN_USAGE. For example:
USE Adb
GO
Select * from INFORMATION_SCHEMA.VIEW_COLUMN_USAGE
where VIEW_NAME='MyView'
GO
Views are just stored SQL scripts that SQL Server adds into your query as a sub select. Consequently the fields used are not actually saved within SQL Server in the same way that table definitions are. Your best bet is to script out all your views using SQL Server Management Studio and plug the files into a tool such as the General SQL Parser which can output the columns and tables that are used in that script.
It isn't perfect but should get you a long way towards what you are trying to achieve. You can try it for free here.

What is the best way to cross reference two SQL Views in Report Builder?

I'm new to SQL queries and need to build a custom report in Microsoft SQL Report Builder 3.0. The data source is a SCCM database. I need help with understanding the best approach to achieve the following:
We need to cross reference if a computer exist in two Views, if so show that name in the report.
InputParameter1 = "Please select a View"
InputParameter2 = "Cross reference with this other View"
If I know the names of the Views beforehand I have a query to get what I need from the SQL server, but I need to create a parameter-based report where you select two Views dynamically and the report cross reference them for you and present which computers exists in both Views.
This is the query I can use for a static result. v_CM_RES_COLL_CMS0020B and v_CM_RES_COLL_CMS000D1 are examples of names of possible Views, until I can solve the parameter issue in Report Builder:
SELECT v_GS_SYSTEM.Name0
FROM v_GS_SYSTEM
WHERE Name0 IN
(SELECT Name from v_CM_RES_COLL_CMS0020B)
AND Name0 IN
(SELECT Name from v_CM_RES_COLL_CMS000D1)
I don't know how to proceed in how to make the above query into a parameter report in Report Builder. Somehow I need to change v_M_RES_COL_CMS00### to what ever the user inputs to the parameters. Does anyone know how? Any help is greatly appreciated.

SSRS - missing data in the table in my report even though no missing data in sql server

I have a stored procedure returning data like:
Id Name fromTable
1 Alison Table1
2 Gary Table2
3 Jack Table1
4 John Table3
by the code:
Select Id, Name, fromTable='Table1' from Table1
union
Select Id, Name, fromTable='Table2' from Table2
union
Select Id, Name, fromTable='Table3' from Table3
I created a report in SSRS 2008, created Dataset1 which is connected to this SP and I am inserting a table to my SSRS report which is connected to Dataset1. However, here I only see the data coming from Table1 (Alison and Gary). I cannot see the data coming from Table2 and Table3. I could not understand why it is happening and how to fix it, because seems like query is working well in the SQL Server 2008. Any help would be appreciated.
Hey I will do couple of things here.
I will run my query in query designer in SSRS(Visual studio) after clicking refresh fields. If you are not getting all data here you have an issue in your query.
I will delete rdl data file, to make sure you are not holding any cache.
I tried the sample data you gave i can see all the data in my SSRS 2008. i will suggest you delete the report and re-create it making sure that the report is pointed to the correct data source
First, validate your data in sql server. Sometimes these SP's do not do exactly what we intended them to do, although your query looks simple enough I would still double check. If that output is what you need then I would suggest just rewriting your ssrs ensuring that your datasource is correct and everything else is jiving. SSRS is super clunky!!!
This is very handy solution to add to your VS:How to add Clear Cache from VS/Tools
to test cache issue, make any notable change in SQL to see if it's coming through.
to test any rdl issues made any notable change in let say Header and run report
if those 2 test passed OK, then check dataset properties (Filters)
if this passed then check Tablix properties (filters), then tablix raw visibility
Check dataset properties (Query type: make sure if it's sp name = corrrect).
Check data SOURCE ! so it points to the right server / db
Is this yours rdl or somebody's else?
J

Resources