Grant permissions on an XML schema collection

Applies to: SQL Server Azure SQL Database Azure SQL Managed Instance

You can grant permissions to create an XML schema collection and also grant permissions on an XML schema collection object.

Grant permission to create an XML schema collection

To create an XML schema collection, the following permissions are required:

  • The principal requires CREATE XML SCHEMA COLLECTION permission at the database-level.

  • Because the XML schema collections are relational schema-scoped, the principal must also have ALTER permission on the relational schema.

The following permissions let a principal create an XML schema collection in a relational schema in a database on a server:

  • CONTROL permission on the server

  • ALTER ANY DATABASE permission on the server

  • ALTER permission on the database

  • CONTROL permission in the database

  • ALTER ANY SCHEMA permission and CREATE XML SCHEMA COLLECTION permission in the database

  • ALTER or CONTROL permission on the relational schema and CREATE XML SCHEMA COLLECTION permission in the database

This last method of permissions is used in the following example.

The owner of the relational schema becomes the owner of the XML schema collection created in that schema. This owner then has full control over the XML schema collection. Therefore, this owner can modify the XML schema collection, type an xml column, or drop the XML schema collection.

Grant permissions on an XML schema collection object

The following permissions are allowed on the XML schema collection:

  • The ALTER permission is required when modifying contents of an existing XML schema collection by using the ALTER XML SCHEMA COLLECTION statement.

  • The CONTROL permission lets a user perform any operation on the XML schema collection.

  • The TAKE OWNERSHIP permission is required to transfer ownership of the XML schema collection from one principal to another.

  • The REFERENCES permission authorizes the principal to use the XML schema collection to type or constrain xml type columns, in tables and views and parameters. The REFERENCES permission is also required when one XML schema collection refers to another.

  • The VIEW DEFINITION permission allows the principal to query the contents of an XML schema collection either through XML_SCHEMA_NAMESPACE or through the catalog views, provided this principal also has one of the ALTER, REFERENCES, or CONTROL permissions on the collection.

  • The EXECUTE permission is required to validate values inserted or updated by the principal against the XML schema collection that is typing or constraining the xml type columns, variables, and parameters. You also need this permission when you're querying the XML stored in these columns and variables.

Examples

The scenarios in the following examples illustrate how XML schema permissions work. Each example creates the necessary test database, relational schemas, and logins. These logins are granted the necessary XML schema collection permissions. Each example does the necessary cleanup at the end.

A. Grant permissions to create an XML schema collection

The following example shows how to grant permissions so that a principal can create an XML schema collection. The example creates a sample database and a test user, TestLogin1. TestLogin1 is then given ALTER permission on the relational schema and given CREATE XML SCHEMA COLLECTION permission on the database. With these permissions, TestLogin1 succeeds in creating a sample XML schema collection.

SETUSER;
GO
USE master;
GO
CREATE LOGIN TestLogin1 WITH password='SQLSvrPwd1';
GO
CREATE DATABASE SampleDBForSchemaPermissions;
GO
USE SampleDBForSchemaPermissions;
GO
CREATE USER TestLogin1;
GO
-- User must have ALTER permission on the relational schema in the database.
GRANT ALTER ON SCHEMA::dbo TO TestLogin1;
GO
-- User also must have permission to create XML schema collections in the database.
GRANT CREATE XML SCHEMA COLLECTION
TO TestLogin1;
GO
-- Execute CREATE XML SCHEMA COLLECTION.
SETUSER 'TestLogin1';
GO
CREATE XML SCHEMA COLLECTION myTestSchemaCollection AS '<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema targetNamespace="https://schemas.adventure-works.com/Additional/ContactInfo"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="AdditionalContactInfo" >
  <xsd:complexType mixed="true" >
    <xsd:sequence>
      <xsd:any processContents="strict"
               namespace="https://schemas.adventure-works.com/Contact/Record
                          https://schemas.adventure-works.com/AdditionalContactTypes"
               minOccurs="0" maxOccurs="unbounded" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>
<xsd:element name="root" type="xsd:byte"/>
</xsd:schema>';
GO
-- Final cleanup
SETUSER;
GO
USE master;
GO
DROP DATABASE SampleDBForSchemaPermissions;
GO
DROP LOGIN TestLogin1;
GO

B. Grant permission to use an existing XML schema collection

The following example further shows the permission model for the XML schema collection. The example shows how different permissions are required to create and use the XML schema collection.

The example creates a test database and a login, TestLogin1. TestLogin1 creates an XML schema collection in the database. The login then creates a table and uses the XML schema collection to create a typed xml column. The user then inserts data and queries it. All these steps require the necessary schema permissions, as shown in the code.

SETUSER
GO
USE master;
GO
CREATE LOGIN TestLogin1 WITH password='SQLSvrPwd1';
GO
CREATE DATABASE SampleDBForSchemaPermissions;
GO
USE SampleDBForSchemaPermissions;
GO
CREATE USER TestLogin1;
GO
-- Grant permission to the user.
SETUSER;
GO
-- User must have ALTER permission on the relational schema in the database.
GRANT ALTER ON SCHEMA::dbo TO TestLogin1;
GO
-- User also must have permission to create XML schema collections in the database.
GRANT CREATE XML SCHEMA COLLECTION
TO TestLogin1;
GO
-- Now user can execute the previous CREATE XML SCHEMA COLLECTION statement.
SETUSER 'TestLogin1';
GO
CREATE XML SCHEMA COLLECTION myTestSchemaCollection AS '<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema targetNamespace="https://schemas.adventure-works.com/Additional/ContactInfo"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">

<xsd:element name="AdditionalContactInfo" >
  <xsd:complexType mixed="true" >
    <xsd:sequence>
      <xsd:any processContents="strict"
               namespace="https://schemas.adventure-works.com/Contact/Record
                          https://schemas.adventure-works.com/AdditionalContactTypes"
               minOccurs="0" maxOccurs="unbounded" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>
<xsd:element name="telephone" type="xsd:string" />
</xsd:schema>';
GO

-- Create a table by using the collection to type an XML column.
--TestLogin1 must have permission to create a table.
SETUSER;
GO
GRANT CREATE TABLE TO TestLogin1;
GO
-- The user also must have REFERENCES permission to use the XML schema collection
-- to create a typed XML column (REFERENCES permission on schema
-- collection is not needed).
GRANT REFERENCES ON XML SCHEMA COLLECTION::myTestSchemaCollection
TO TestLogin1;
GO
-- Now user can create a table and use the XML schema collection to create
-- a typed XML column.
SETUSER 'TestLogin1';
GO
CREATE TABLE MyTestTable (xmlCol xml (dbo.myTestSchemaCollection));
GO
-- To insert data in the table, the user needs EXECUTE permission on the XML schema collection.
-- GRANT EXECUTE permission to TestLogin2 on the xml schema collection.
SETUSER;
GO
GRANT EXECUTE ON XML SCHEMA COLLECTION::myTestSchemaCollection
TO TestLogin1;
GO
-- TestLogin1 does not own the dbo schema. This user must have INSERT permission.
GRANT INSERT TO TestLogin1;
GO
-- Now the user can insert data into the table.
SETUSER 'TestLogin1';
GO
INSERT INTO MyTestTable VALUES('
<telephone xmlns="http://schemas.adventure-works.com/Additional/ContactInfo">111-1111</telephone>
');
GO
-- To query the table, TestLogin1 must have permissions: SELECT on the table and EXECUTE on the XML schema collection.
SETUSER
GO
GRANT SELECT TO TestLogin1;
GO
-- TestLogin1 already has EXECUTE permission on the schema (granted before inserting a record in the table).
SELECT xmlCol.query('declare default element namespace "https://schemas.adventure-works.com/Additional/ContactInfo"; /telephone[1]')
FROM MyTestTable;
GO
-- To show that the user must have EXECUTE permission to query, revoke the
-- previously granted permission and return the query.
SETUSER;
GO
REVOKE EXECUTE ON XML SCHEMA COLLECTION::myTestSchemaCollection to TestLogin1;
GO
-- Now TestLogin1 cannot execute the query.
SETUSER 'TestLogin1';
GO
SELECT xmlCol.query('declare default element namespace "https://schemas.adventure-works.com/Additional/ContactInfo"; /telephone[1]')
FROM MyTestTable;
GO
-- Final cleanup
SETUSER;
GO
USE master;
GO
DROP DATABASE SampleDBForSchemaPermissions;
GO
DROP LOGIN TestLogin1;
GO

C. Grant ALTER permission on an XML schema collection

A user must have ALTER permission to modify an existing XML schema collection in the database. The following example shows how to grant ALTER permission.

SETUSER;
GO
USE master;
GO
CREATE LOGIN TestLogin1 WITH password='SQLSvrPwd1';
GO
CREATE DATABASE SampleDBForSchemaPermissions;
GO
USE SampleDBForSchemaPermissions;
GO
CREATE USER TestLogin1;
GO
-- Grant permission to the user.
SETUSER;
GO
-- User must have ALTER permission on the relational schema in the database.
GRANT ALTER ON SCHEMA::dbo TO TestLogin1;
GO
-- User also must have permission to create XML schema collections in the database.
GRANT CREATE XML SCHEMA COLLECTION
TO TestLogin1;
GO
-- Now user can execute the previous CREATE XML SCHEMA COLLECTION statement.
SETUSER 'TestLogin1';
GO
CREATE XML SCHEMA COLLECTION myTestSchemaCollection AS '<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema targetNamespace="https://schemas.adventure-works.com/Additional/ContactInfo"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">

<xsd:element name="AdditionalContactInfo" >
  <xsd:complexType mixed="true" >
    <xsd:sequence>
      <xsd:any processContents="strict"
               namespace="https://schemas.adventure-works.com/Contact/Record
                          https://schemas.adventure-works.com/AdditionalContactTypes"
               minOccurs="0" maxOccurs="unbounded" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>
<xsd:element name="telephone" type="xsd:string" />
</xsd:schema>';
GO
-- Grant ALTER permission to TestLogin1.
SETUSER;
GO
GRANT ALTER ON XML SCHEMA COLLECTION::myTestSchemaCollection TO TestLogin1;
GO
-- TestLogin1 should be able to add components to the collection.
SETUSER 'TestLogin1';
GO
ALTER XML SCHEMA COLLECTION myTestSchemaCollection ADD '
<xsd:schema targetNamespace="https://schemas.adventure-works.com/Additional/ContactInfo"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://schemas.adventure-works.com/Additional/ContactInfo"
elementFormDefault="qualified">
<xsd:element name="pager" type="xsd:string"/>
</xsd:schema>';
GO
-- Final cleanup
SETUSER;
GO
USE master;
GO
DROP DATABASE SampleDBForSchemaPermissions;
GO
DROP LOGIN TestLogin1;
GO

D. Grant TAKE OWNERSHIP permission on an XML schema collection

The following example shows how to transfer XML schema ownership from one user to another. To make the example more interesting, the users in this example work in different default relational schemas.

This example does the following:

  • Creates a database with two relational schemas, dbo and myOtherDBSchema).

  • Creates two users, TestLogin1 and TestLogin2. TestLogin2 is made the owner of the myOtherDBSchema relational schema.

  • TestLogin1 creates an XML schema collection in the dbo relational schema.

  • TestLogin1 then gives TAKE OWNERSHIP permission on the XML schema collection to TestLogin2.

  • TestLogin2 becomes the owner of the XML schema collection in myOtherDBSchema, without changing the relational schema of the XML schema collection.

CREATE LOGIN TestLogin1 with password='SQLSvrPwd1';
GO
CREATE LOGIN TestLogin2 with password='SQLSvrPwd2';
GO
CREATE DATABASE SampleDBForSchemaPermissions;
GO
USE SampleDBForSchemaPermissions;
GO
-- Create another relational schema in the database.
CREATE SCHEMA myOtherDBSchema;
GO
-- Create users in the database. Note TestLogin2's default schema is
-- myOtherDBSchema.
CREATE USER TestLogin1;
GO
CREATE USER TestLogin2 WITH DEFAULT_SCHEMA=myOtherDBSchema;
GO
-- TestLogin2 will own myOtherDBSchema relational schema.
ALTER AUTHORIZATION ON SCHEMA::myOtherDBSchema TO TestLogin2;
GO

-- For TestLogin1 to create XML schema collection, the following
-- permission is required.
GRANT CREATE XML SCHEMA COLLECTION
TO TestLogin1;
GO
GRANT ALTER ON SCHEMA::dbo TO TestLogin1;
GO
-- Now TestLogin1 can create an XML schema collection.
SETUSER 'TestLogin1';
GO
CREATE XML SCHEMA COLLECTION myTestSchemaCollection AS '<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema targetNamespace="https://schemas.adventure-works.com/Additional/ContactInfo"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">

<xsd:element name="AdditionalContactInfo" >
<xsd:complexType mixed="true" >
    <xsd:sequence>
      <xsd:any processContents="strict"
               namespace="https://schemas.adventure-works.com/Contact/Record
                          https://schemas.adventure-works.com/AdditionalContactTypes"
               minOccurs="0" maxOccurs="unbounded" />
    </xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="telephone" type="xsd:string" />
</xsd:schema>';
GO

-- Grant TAKE OWNERSHIP to TestLogin2.
SETUSER;
GO
GRANT TAKE OWNERSHIP ON XML SCHEMA COLLECTION::dbo.myTestSchemaCollection
TO TestLogin2;
GO
-- Verify the owner. Note the UserName and Principal_id is null.
SELECT user_name(sys.xml_schema_collections.principal_id) as UserName,
       sys.schemas.name as RelSchemaName,*
FROM   sys.xml_schema_collections
      JOIN sys.schemas
      ON sys.schemas.schema_id=sys.xml_schema_collections.schema_id;
GO
-- TestLogin2 can take ownership now.
SETUSER 'TestLogin2';
GO
ALTER AUTHORIZATION ON XML SCHEMA COLLECTION::dbo.myTestSchemaCollection
TO TestLogin2;
GO
-- Note that although TestLogin2 is the owner,the XML schema collection
-- is still in dbo.
SELECT user_name(sys.xml_schema_collections.principal_id) as UserName,
      sys.schemas.name as RelSchemaName,*
FROM sys.xml_schema_collections JOIN sys.schemas
     ON sys.schemas.schema_id=sys.xml_schema_collections.schema_id;
GO

-- TestLogin2 moves the collection from dbo to myOtherDBSchema relational schema.
-- TestLogin2 already has all necessary permissions.
-- 1) TestLogin2 owns the destination relational schema so he can alter it.
-- 2) TestLogin2 owns the XML schema collection (therefore, has CONTROL permission).
ALTER SCHEMA myOtherDBSchema
TRANSFER XML SCHEMA COLLECTION::dbo.myTestSchemaCollection;
GO

SELECT user_name(sys.xml_schema_collections.principal_id) as UserName,
       sys.schemas.name as RelSchemaName,*
FROM   sys.xml_schema_collections JOIN sys.schemas
       ON sys.schemas.schema_id=sys.xml_schema_collections.schema_id;
GO
-- Final cleanup
SETUSER;
GO
USE master;
GO
DROP DATABASE SampleDBForSchemaPermissions;
GO
DROP LOGIN TestLogin1;
DROP LOGIN TestLogin2;
GO

E. Grant VIEW DEFINITION permission on an XML schema collection

The following example shows how to grant VIEW DEFINITION permissions for an XML schema collection.

SETUSER;
GO
USE master;
GO
IF EXISTS( SELECT * FROM sysdatabases WHERE name='permissionsDB' )
   DROP DATABASE permissionsDB;
GO
IF EXISTS( SELECT * FROM sys.sql_logins WHERE name='schemaUser' )
   DROP LOGIN schemaUser;
GO
CREATE DATABASE permissionsDB;
GO
CREATE LOGIN schemaUser WITH PASSWORD='Pass#123',DEFAULT_DATABASE=permissionsDB;
GO
GRANT CONNECT SQL TO schemaUser;
GO
USE permissionsDB;
GO
CREATE USER schemaUser WITH DEFAULT_SCHEMA=dbo;
GO
CREATE XML SCHEMA COLLECTION MySC AS '
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ns"
xmlns:ns="http://ns">
   <simpleType name="ListOfIntegers">
      <list itemType="integer"/>
   </simpleType>
   <element name="root" type="ns:ListOfIntegers"/>
   <element name="gRoot" type="gMonth"/>
</schema>';
GO
-- schemaUser cannot see the contents of the collection.
SETUSER 'schemaUser';
GO
SELECT XML_SCHEMA_NAMESPACE(N'dbo',N'MySC');
GO

-- Grant schemaUser VIEW DEFINITION and REFERENCES permissions
-- on the XML schema collection.
SETUSER;
GO
GRANT VIEW DEFINITION ON XML SCHEMA COLLECTION::dbo.MySC TO schemaUser;
GO
GRANT REFERENCES ON XML SCHEMA COLLECTION::dbo.MySC TO schemaUser;
GO
-- Now schemaUser can see the content of the collection.
SETUSER 'schemaUser';
GO
SELECT XML_SCHEMA_NAMESPACE(N'dbo',N'MySC');
GO
-- Revoke schemaUser VIEW DEFINITION permissions
-- on the XML schema collection.
SETUSER;
GO
REVOKE VIEW DEFINITION ON XML SCHEMA COLLECTION::dbo.MySC FROM schemaUser;
GO
-- Now schemaUser cannot see the contents of
-- the collection.
SETUSER 'schemaUser';
GO
SELECT XML_SCHEMA_NAMESPACE(N'dbo',N'MySC');
GO

See also