How to find the columns and tables used in a stored procedure (SQL Server)
Update: You can get the information from a non-deprecated dynamic management function rather then the older dynamic management view, as pointed out by dfundako in the comments below. This would be the recommended approach as the function is available in all currently supported SQL Server releases and likely to be so in at least the next few releases too.

To update my previous example:

CREATE PROCEDURE test_depends 
AS BEGIN
    SELECT TOP 5 ou_id, prop_text FROM tr_n_ou WHERE prop_name = 'display_name'
    SELECT * FROM tr_n_org WHERE parent_display_name = 'Global'
    EXEC some_stored_procedure
END
GO

SELECT ISNULL(referenced_schema_name+'.','')+referenced_entity_name+ISNULL('.'+referenced_minor_name,'') AS Dependency
     , ISNULL(so.type_desc, sn.type_desc) AS DependencyType
     , CASE WHEN ISNULL(so.type_desc, sn.type_desc) IN ('USER_TABLE', 'VIEW') 
            AND referenced_minor_name IS NOT NULL
            THEN 'Column in '
            ELSE ''
            END
     + ISNULL(so.type_desc, sn.type_desc) AS DependencySubType
FROM sys.dm_sql_referenced_entities('dbo.test_depends', 'OBJECT') sr 
LEFT OUTER JOIN 
     sys.objects so 
     ON  so.object_id = sr.referenced_id
LEFT OUTER JOIN 
     sys.objects sn 
     ON  sn.name = sr.referenced_entity_name 
     AND sr.referenced_id IS NULL

GO
DROP PROCEDURE test_depends 


The caveats about ad-hoc SQL still apply.

Also if a procedure references something that is user schema dependent the referenced ID will be NULL in the DMF which is why I'm doing the extra lookup by name in this example. If the EXEC line specified a schema (i.e. EXEC some_schema.some_procedure) then the ID would have a value so the ID lookup would work, otherwise there could be several procedures with the same name in different schemas and the one called will depend on run-type details. Note also that the name lookup will return multiple rows for the same dependency in this case if there are multiple procedures of the same name.

________________________________________

Previous answer:

You can get this information, mostly, from sys.sql_dependencies but be aware that this is marked for deprecation so may not be available in future versions of SQL Server.

To test in one of your databases do something like:

CREATE PROCEDURE test_depends 
AS BEGIN
    SELECT TOP 5 column1, column2 FROM some_table WHERE column3 = 'some value'
    SELECT * FROM another_table
    EXEC some_stored_procdure
END
GO

SELECT sd.*, so.name, sc.name
FROM   sys.sql_dependencies sd
LEFT OUTER JOIN
       sys.objects so 
       ON  so.object_id = sd.referenced_major_id
LEFT OUTER JOIN
       sys.columns sc 
       ON  sc.object_id = sd.referenced_major_id 
       AND sc.column_id = sd.referenced_minor_id
WHERE sd.object_id = (SELECT object_id FROM sys.objects WHERE name = 'test_depends')

GO
DROP PROCEDURE test_depends 


You will see that is correctly lists the individual columns for the first table the procedure references, all columns in the second table as that selects *, and the procedure it calls.

Note that this does not deference views so you need a recursive query to get down to the base tables if that is your requirement, and you'll need to dig further too if a procedure calls other procedures.

Note again that sys.sql_dependencies is flagged as deprecated. I ran the above on a 2008r2 instance, the documentation on MSDN seems to list it only as far as 2014 so it may not be present in 2016 (I don't have access to any instances above 2012 in my current location in order to test this) though Kris notes in comments below that the view is still present in 2016. The replacement (sys.sql_expression_dependencies) doesn't list individual columns, at least in my test on a 2008r2 instance (the is only one entry per table with the minor ID 0 is both cases).

Another important thing to consider is that this view can't contain any references made by ad-hoc SQL run via EXEC (&lt;string&gt;) if you have such evilness in your procedures.