I have two schemas, one contains tables, stored procedures, general data (will call it data schemas from now on). The second schema has nothing but stored procedures inside of it and we'll call this execute schema.
Now the point of the execute schema is so that I can create a user (we'll call this external user), which only has access to this schema and can only execute stored procedure within the execute schema... no select, update, insert, delete nothing (there are no tables anyway in the execute schema) and has zero access to the data schema. This way the user will be very restricted in what it can do.
The point in this is that, when a stored procedure is created with the "execute schema" it elevates the user rights depending on what is required, without actually giving the external user any rights past that execution.
All is well, and I have it executing and get data from the data schema with a test stored procedure. I'm now trying to allow one of the stored procedure in the execute schema to use a user-defined table type, which has been created on the data schema. Due to the user restrictions of not being able to see anything of the data schema it is proving to be a problem.
Now I could recreate the data type or move it to a shared schema... but this is a live old database and ideally I don't want to duplicate types or have to move user-defined stuff every time I wish to allow access to the external user.
So I thought about using Aliases. although when I try to create said alias I get an error:
command:
CREATE TYPE [execute].[udtype1] FROM [data].[udtype1] NOT NULL;
error:
The base type "data.udtype1" is not a valid base type for the alias data type.
While I don't know how to do it, I have noticed that the microsoft documentation creates an utf8string and references it (I'm hoping this means what I want to do, can be done and exists):
CREATE ASSEMBLY utf8string
AUTHORIZATION [dbi]
FROM 0x4D... ;
GO
CREATE TYPE Utf8String
EXTERNAL NAME utf8string.[Microsoft.Samples.SqlServer.utf8string] ;
GO
Does anyone know how to create an alias for a user-defined table, or have an alternative approach.
Quote from comment on the original question:
Alias data types are for scalar data types, you can't create an alias data type of a table type. You'll need to give explicit access to the types on the schema here so that the USER's can declare a parameter of the type. –
User: Larnu
He gave me a couple of keywords which helped with my google search.
https://learn.microsoft.com/en-us/sql/t-sql/statements/grant-type-permissions-transact-sql?view=sql-server-ver15
It is still weird though, as I had allow execution and after giving them rights on the specific stored procedure, I could then remove the rights and it works. Trying to remove the rights first results in the execution failing.
I'm in the process of migrating a bunch of existing databases to a Visual Studio project so it can be put in source control. Unfortunately there is 1 stored procedure which uses a table on which change tracking is enabled. It contains a left join to the following nested select statement:
(select distinct ch.batch_number from CHANGETABLE(CHANGES dbName.dbo.batchTable, 0) as ch)
This gives the following warning:
SQL71562: Procedure: [dbo].[stMergeBatchInfo] contains an unresolved reference to an object. Either the object does not exist or the reference is ambiguous because it could refer to any of the following objects: [CT].[batch_number] or [CT].[ch]::[batch_number].
It indicates that the column ch.batch_number is unknown. It appears that when the CHANGETABLE function is used the column definition is unknown to the project. The table being read is referenced through a DACPAC file and can be used in standard SELECT statements just fine.
Does anyone know if there any way to get rid of these build warnings? Target SQL server is 2016. The database and table names are dummy names by the way.
I had a similar issue and actually came here looking for an answer. There are 2 things that might help
Make sure you have master referenced in your proj. under the proj right click references and add system master.
I did a schema compare from the db to the project and noticed my table was missing 'ALTER TABLE [dbo].[History_Table] ENABLE CHANGE_TRACKING'
I hope either of these help you out.
I've encountered this before. In my case, the version of the master database reference didn't match the version of the Database Project.
In my sqlproj file, the version of the database is 2014 (120).
<DSP>
Microsoft.Data.Tools.Schema.Sql.Sql120DatabaseSchemaProvider
</DSP>
Next, ensure your master database reference is the same version (120).
<ArtifactReference Include="$(DacPacRootPath)\Extensions\Microsoft\SQLDB\Extensions\SqlServer\120\SqlSchemas\master.dacpac">
<HintPath>
$(DacPacRootPath)\Extensions\Microsoft\SQLDB\Extensions\SqlServer\120\SqlSchemas\master.dacpac
</HintPath>
<SuppressMissingDependenciesErrors>
False
</SuppressMissingDependenciesErrors>
<DatabaseVariableLiteralValue>
master
</DatabaseVariableLiteralValue>
</ArtifactReference>
Thanks
How to get user defined data type (not table type) creation time in MSSQL?
sys.types has no appropriate column and types are not listed in sys.all_objects, so it looks like something not supported by SQL server.
Another thing that potentially hints this is not available is that most of other object types have both create_date/modify_date. Types have no ALTER command so they definitely have no modify date.
Leaving answer as this is not possible for now, because that's what I've found so far.
In some Snowflake databases I can run SELECT GET_DDL('Database', 'MyDatabase'); without problem but in another one, I get the following error message
SQL compilation error: Invalid object type: 'EXTERNAL_TABLE'
There might be an external defined in that database but I would still like to extract the DDL recursively on the database...
Is there any trick I could use?
You could try using DESCRIBE EXTERNAL TABLE which describes the virtual columns on the table.
DESCRIBE EXTERNAL TABLE
5.8 Release Notes - March 15-18, 2021
GET_DDL Function: External Table Support
With this release, the GET_DDL function supports returning a DDL statement that can be used to recreate a specified external table.
Note that currently, the GET_DDL output for a specified database or schema does not include any external tables contained in the schema.
I created SQL Server Database Project in VS 2012 & imported our database.
When I build the project, I get a lot of "unresolved reference to object" Errors.
These errors are only for a few views I have in my database.
The syntax for these views are correct & I am not using temp tables.
What should I check to solve this issue?
UPDATE:
This is one example:
CREATE view [Factory].[NonStartedOrders]
as
SELECT
"Customers"."CustomerName", "Customers"."CustomerAName",
"Customers"."MarketID",
"Orders"."OrderID",
"Orders"."ApproveDate",
"FactoryOrders"."FactoryID",
"FactoryOrders"."EstEndDate",
"FactoryOrders"."StatusID",
"FactoryOrders"."TotalWeight",
"Karats"."KaratEName"
FROM (("Taiba"."Sales"."FactoryOrders" "FactoryOrders"
INNER JOIN "Taiba"."Sales"."Orders" "Orders" ON "FactoryOrders"."OrderID"="Orders"."OrderID")
INNER JOIN "Taiba"."General"."Customers" "Customers" ON "Orders"."CustomerID"="Customers"."CustomerID")
INNER JOIN "Taiba"."MasterPiece"."Karats" "Karats" ON "Orders"."MKaratID"="Karats"."KaratID"
"Taiba" here is my database name.
I am getting 30 errors only for this view.
These are a few errors of them:
Error 217 SQL71561: View: [Factory].[NonStartedOrders] has an unresolved reference to object [Taiba].[Sales].[FactoryOrders]
Error 219 SQL71561: View: [Factory].[NonStartedOrders] contains an unresolved reference to an object. Either the object does not exist or the reference is ambiguous because it could refer to any of the following objects: [Taiba].[Sales].[FactoryOrders].[FactoryOrders]::[OrderID], [Taiba].[Sales].[FactoryOrders].[OrderID] or [Taiba].[Sales].[Orders].[FactoryOrders]::[OrderID].
One other possibility is that the schema you have used in your view/table etc does not exist in the project. You may need to add the schema to the VS Database Project.
Right Click the project and Add > New Item > Schema
I solved this issue.
It seems a few of my views/SPs have referenced the tables using this naming convention ( 3 parts qualified name ):
DatabaseName.SchemaName.TableName
I changed all references to be as the following:
SchemaName.TableName
In my case, the function that couldn't be found was of Build Action=None and so it wasn't being included in the compile.
Changing the Build Action to Build corrected this.
This happened to me when building a CTE in Visual Studio 2015. I changed the Build Action to Compile and the errors went away.
Select the file(s) with the error
Press F4 to see the properties.
Select 'Compile' in the Build Action drop down list.
Hope this helps someone.
To reference another sqlproj's schema and use three-part naming, modify your .sqlproj file to add a DatabaseVariableLiteralValue element on the referenced project.
In within the element like
<ProjectReference Include="..\SomeDatabaseProject\SomeDatabaseProject.sqlproj">, add the following:
<DatabaseVariableLiteralValue>SomeDatabaseProject</DatabaseVariableLiteralValue>
For example:
<ProjectReference Include="..\SomeDatabaseProject\SomeDatabaseProject.sqlproj">
<Name>SomeDatabaseProject</Name>
<Project>{some-project-guid}</Project>
<Private>True</Private>
<DatabaseVariableLiteralValue>SomeDatabaseProject</DatabaseVariableLiteralValue>
</ProjectReference>
Then you can use clean, three-part naming references like SomeDatabaseProject.SomeSchema.SomeTable.
It is possible that the objects are inside NotInBuild tag in the project file for naming or other issue. In my case I saved the file with ..sql and the extra dot was causing it to move under NotInBuild tag inside project file. I corrected the extension and moved the missing object under build tag and that resolved the issue.
Try explicitly defining the class:
class: Specifies the class of the securable on which the permission is being
granted. The scope qualifier :: is required.
Read the docs on the SQL GRANT statement: http://technet.microsoft.com/en-us/library/ms187965.aspx
In my case I had a User Defined Table Type.
GRANT EXECUTE ON TYPE::[dbo].[MessageTableType] TO [PostOffice_Role];
You will also get this error when you add a table (using .sql file ) and if you do not check-in the .sqlproj file
This may be an edge case but if in your object definition you are also documenting the object (we do, anyway...) using sp_addextendedproperty you can also get this error if you have stated an incorrect object type - which can happen if copy & pasting. The "unresolved reference to object" error makes sense here when you think about it.
For example the following will recreate the error as the level1type should be 'PROCEDURE' and not 'FUNCTION'.
EXEC sp_addextendedproperty
#name = N'MS_Description',
#value = N'Description of the stored procedure...',
#level0type = N'SCHEMA',
#level0name = N'dbo',
#level1type = FUNCTION',
#level1name = N'spMyStoredProcedureName'
GO
I have a DacPac project containing objects which use three part naming to refer to the containing database (hundreds of instances such as [thisDb].[dbo].[obj]* exist). I need compare and update this database, but the db project fails to build due to 200+ sql71561 errors.
I did not want to remove the unnecessary database name part or switch to using a database name variable. To successfully build, (properly) compare, and then update a database using three part naming or fully qualified naming to refer to itself, there is a way to pacify visual studio:
Create a copy of the original db project.
In the copy db project, update all local database object references to use just two part names ([dbo].[obj]) instead of three part names (I used find & replace).
Make sure the copy db project targets the same SQL server version and builds successfully.
Reference the copy db project from the original db project (whether via database variable, database name only, or dacpac).
The original db project can now build because its references can be resolved.
The original db project can now be used to update the actual database in SQL Server after a compare.
A recompare after the update shows a flawless victory.