SQL 2014 - Views
SQL 2014 - Views
SQL 2014 - Views
This document is provided "as‐is". Information and views expressed in this document, including URL
and other Internet Web site references, may change without notice. This document does not provide
you with any legal rights to any intellectual property in any Microsoft product or product name. You
may copy and use this document for your internal, reference purposes. You may modify this document
for your internal, reference purposes.© 2016 Microsoft. All rights reserved. Terms of Use
﴾https://msdn.microsoft.com/cc300389.aspx﴿ | Trademarks
﴾http://www.microsoft.com/library/toolbar/3.0/trademarks/en‐us.mspx﴿
Table Of Contents
Views
Views
System Views ﴾Transact‐SQL﴿
Create Views
Create Views
Create Indexed Views
CREATE VIEW ﴾Transact‐SQL﴿
Create Views over XML Columns
Modify Views
Modify Views
ALTER VIEW ﴾Transact‐SQL﴿
Modify Data Through a View
UPDATE ﴾Transact‐SQL﴿
INSERT ﴾Transact‐SQL﴿
Rename Views
Rename Views
Delete Views
Delete Views
DROP VIEW ﴾Transact‐SQL﴿
Views
Views
SQL Server 2016
A view is a virtual table whose contents are defined by a query. Like a table, a view consists of a set
of named columns and rows of data. Unless indexed, a view does not exist as a stored set of data
values in a database. The rows and columns of data come from tables referenced in the query
defining the view and are produced dynamically when the view is referenced.
A view acts as a filter on the underlying tables referenced in the view. The query that defines the
view can be from one or more tables or from other views in the current or other databases.
Distributed queries can also be used to define views that use data from multiple heterogeneous
sources. This is useful, for example, if you want to combine similarly structured data from different
servers, each of which stores data for a different region of your organization.
Views are generally used to focus, simplify, and customize the perception each user has of the
database. Views can be used as security mechanisms by letting users access data through the view,
without granting the users permissions to directly access the underlying base tables of the view.
Views can be used to provide a backward compatible interface to emulate a table that used to
exist but whose schema has changed. Views can also be used when you copy data to and from
SQL Server to improve performance and to partition data.
Types of Views
Besides the standard role of basic user‐defined views, SQL Server provides the following types
of views that serve special purposes in a database.
Indexed Views
An indexed view is a view that has been materialized. This means the view definition has
been computed and the resulting data stored just like a table. You index a view by
creating a unique clustered index on it. Indexed views can dramatically improve the
performance of some types of queries. Indexed views work best for queries that
aggregate many rows. They are not well‐suited for underlying data sets that are
frequently updated.
Partitioned Views
A partitioned view joins horizontally partitioned data from a set of member tables across
one or more servers. This makes the data appear as if from one table. A view that joins
member tables on the same instance of SQL Server is a local partitioned view.
System Views
System views expose catalog metadata. You can use system views to return information
about the instance of SQL Server or the objects defined in the instance. For example, you
can query the sys.databases catalog view to return information about the user‐defined
databases available in the instance. For more information, see System Views ﴾Transact‐
SQL﴿
Describes how to return information about a view such as the Get Information About a
view definition. View
See Also
Create Views over XML Columns
CREATE VIEW ﴾Transact‐SQL﴿
© 2016 Microsoft
Microsoft SQL Server provides the following collections of system views that expose metadata.
Catalog Views Information Schema Views
See Also
Reference
System Tables ﴾Transact‐SQL﴿
Mapping System Tables to System Views ﴾Transact‐SQL﴿
Concepts
Querying the SQL Server System Catalog FAQ
Metadata Access, Isolation Levels, and Lock Hints
© 2016 Microsoft
Create Views
Create Views
SQL Server 2014
You can create views in SQL Server 2014 by using SQL Server Management Studio or Transact‐SQL.
A view can be used for the following purposes:
To focus, simplify, and customize the perception each user has of the database.
As a security mechanism by allowing users to access data through the view, without
granting the users permissions to directly access the underlying base tables.
To provide a backward compatible interface to emulate a table whose schema has changed.
In This Topic
Using Transact‐SQL
Security
Permissions
Requires CREATE VIEW permission in the database and ALTER permission on the schema in
which the view is being created.
1. In Object Explorer, expand the database where you want to create your new view.
3. In the Add Table dialog box, select the element or elements that you want to include in
your new view from one of the following tabs: Tables, Views, Functions, and Synonyms.
5. In the Diagram Pane, select the columns or other elements to include in the new view.
6. In the Criteria Pane, select additional sort or filter criteria for the columns.
7. On the File menu, click Saveview name.
8. In the Choose Name dialog box, enter a name for the new view and click OK.
For more information about the query and view designer, see Query and View Designer
Tools ﴾Visual Database Tools﴿.
Using Transact-SQL
To create a view
3. Copy and paste the following example into the query window and click Execute.
USE AdventureWorks2012 ;
GO
CREATE VIEW HumanResources.EmployeeHireDate
AS
SELECT p.FirstName, p.LastName, e.HireDate
FROM HumanResources.Employee AS e JOIN Person.Person AS p
ON e.BusinessEntityID = p.BusinessEntityID ;
GO
‐‐ Query the view
SELECT FirstName, LastName, HireDate
FROM HumanResources.EmployeeHireDate
ORDER BY LastName;
© 2016 Microsoft
This topic describes how to create an indexed view in SQL Server 2014 by using Transact‐SQL. The
first index created on a view must be a unique clustered index. After the unique clustered index
has been created, you can create more nonclustered indexes. Creating a unique clustered index on
a view improves query performance because the view is stored in the database in the same way a
table with a clustered index is stored. The query optimizer may use indexed views to speed up the
query execution. The view does not have to be referenced in the query for the optimizer to
consider that view for a substitution.
In This Topic
Recommendations
Considerations
Security
Using Transact‐SQL
1. Verify the SET options are correct for all existing tables that will be referenced in the view.
2. Verify that the SET options for the session are set correctly before you create any tables
and the view.
To make sure that the views can be maintained correctly and return consistent results,
indexed views require fixed values for several SET options. The SET options in the following
table must be set to the values shown in the RequiredValue column whenever the following
conditions occur:
There is any insert, update, or delete operation performed on any table that
participates in the indexed view. This requirement includes operations such as bulk
copy, replication, and distributed queries.
The indexed view is used by the query optimizer to produce the query plan.
Default
Default
Default
Required
SET options server DB‐
value OLE DB and
value Library
ODBC value
value
ANSI_NULLS ON ON ON OFF
ANSI_PADDING ON ON ON OFF
ANSI_WARNINGS* ON ON ON OFF
CONCAT_NULL_YIELDS_NULL ON ON ON OFF
QUOTED_IDENTIFIER ON ON ON OFF
If you are using an OLE DB or ODBC server connection, the only value that must be modified
is the ARITHABORT setting. All DB‐Library values must be set correctly either at the server
level by using sp_configure or from the application by using the SET command.
Important
We strongly recommend that you set the ARITHABORT user option to ON server‐wide as
soon as the first indexed view or index on a computed column is created in any database
on the server.
Deterministic Views
The definition of an indexed view must be deterministic. A view is deterministic if all
expressions in the select list, as well as the WHERE and GROUP BY clauses, are deterministic.
Deterministic expressions always return the same result any time they are evaluated with a
specific set of input values. Only deterministic functions can participate in deterministic
expressions. For example, the DATEADD function is deterministic because it always returns
the same result for any given set of argument values for its three parameters. GETDATE is not
deterministic because it is always invoked with the same argument, but the value it returns
changes each time it is executed.
To determine whether a view column is deterministic, use the IsDeterministic property of the
COLUMNPROPERTY function. To determine if a deterministic column in a view with schema
binding is precise, use the IsPrecise property of the COLUMNPROPERTY function.
COLUMNPROPERTY returns 1 if TRUE, 0 if FALSE, and NULL for input that is not valid. This
means the column is not deterministic or not precise.
Even if an expression is deterministic, if it contains float expressions, the exact result may
depend on the processor architecture or version of microcode. To ensure data integrity, such
expressions can participate only as non‐key columns of indexed views. Deterministic
expressions that do not contain float expressions are called precise. Only precise deterministic
expressions can participate in key columns and in WHERE or GROUP BY clauses of indexed
views.
Additional Requirements
In addition to the SET options and deterministic function requirements, the following
requirements must be met:
The user that executes CREATE INDEX must be the owner of the view.
When you create the index, the IGNORE_DUP_KEY option must be set to OFF ﴾the
default setting﴿.
User‐defined functions referenced in the view must be created by using the WITH
SCHEMABINDING option.
The data access property of a user‐defined function must be NO SQL, and external
access property must be NO.
Common language runtime ﴾CLR﴿ functions can appear in the select list of the view,
but cannot be part of the definition of the clustered index key. CLR functions cannot
appear in the WHERE clause of the view or the ON clause of a JOIN operation in the
view.
CLR functions and methods of CLR user‐defined types used in the view definition must
have the properties set as shown in the following table.
Property Note
The view must reference only base tables that are in the same database as the view.
The view cannot reference other views.
The SELECT statement in the view definition must not contain the following Transact‐
SQL elements:
CHECKSUM_AGG
*The indexed view can contain float columns; however, such columns cannot be
included in the clustered index key.
If GROUP BY is present, the VIEW definition must contain COUNT_BIG﴾*﴿ and must not
contain HAVING. These GROUP BY restrictions are applicable only to the indexed view
definition. A query can use an indexed view in its execution plan even if it does not
satisfy these GROUP BY restrictions.
If the view definition contains a GROUP BY clause, the key of the unique clustered
index can reference only the columns specified in the GROUP BY clause.
Recommendations
When you refer to datetime and smalldatetime string literals in indexed views, we
recommend that you explicitly convert the literal to the date type you want by using a
deterministic date format style. For a list of the date format styles that are deterministic, see
CAST and CONVERT ﴾Transact‐SQL﴿. Expressions that involve implicit conversion of character
strings to datetime or smalldatetime are considered nondeterministic. This is because the
results depend on the LANGUAGE and DATEFORMAT settings of the server session. For
example, the results of the expression CONVERT (datetime, '30 listopad 1996', 113)
depend on the LANGUAGE setting because the string 'listopad' means different months in
different languages. Similarly, in the expression DATEADD(mm,3,'2000‐12‐01'), SQL Server
interprets the string '2000‐12‐01' based on the DATEFORMAT setting.
Considerations
The setting of the large_value_types_out_of_row option of columns in an indexed view is
inherited from the setting of the corresponding column in the base table. This value is set by
using sp_tableoption. The default setting for columns formed from expressions is 0. This
means that large value types are stored in‐row.
Indexed views can be created on a partitioned table, and can themselves be partitioned.
To prevent the Database Engine from using indexed views, include the OPTION ﴾EXPAND
VIEWS﴿ hint on the query. Also, if any of the listed options are incorrectly set, this will prevent
the optimizer from using the indexes on the views. For more information about the OPTION
﴾EXPAND VIEWS﴿ hint, see SELECT ﴾Transact‐SQL﴿.
All indexes on a view are dropped when the view is dropped. All nonclustered indexes and
auto‐created statistics on the view are dropped when the clustered index is dropped. User‐
created statistics on the view are maintained. Nonclustered indexes can be individually
dropped. Dropping the clustered index on the view removes the stored result set, and the
optimizer returns to processing the view like a standard view.
Indexes on tables and views can be disabled. When a clustered index on a table is disabled,
indexes on views associated with the table are also disabled.
Security
Permissions
Requires CREATE VIEW permission in the database and ALTER permission on the schema in
which the view is being created.
Using Transact-SQL
3. Copy and paste the following example into the query window and click Execute. The
example creates a view and an index on that view. Two queries are included that use the
indexed view.
USE AdventureWorks2012;
GO
‐‐Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT,
QUOTED_IDENTIFIER, ANSI_NULLS ON;
GO
‐‐Create view with schemabinding.
IF OBJECT_ID ('Sales.vOrders', 'view') IS NOT NULL
DROP VIEW Sales.vOrders ;
GO
CREATE VIEW Sales.vOrders
WITH SCHEMABINDING
AS
SELECT SUM(UnitPrice*OrderQty*(1.00‐UnitPriceDiscount)) AS Revenue,
OrderDate, ProductID, COUNT_BIG(*) AS COUNT
FROM Sales.SalesOrderDetail AS od, Sales.SalesOrderHeader AS o
WHERE od.SalesOrderID = o.SalesOrderID
GROUP BY OrderDate, ProductID;
GO
‐‐Create an index on the view.
CREATE UNIQUE CLUSTERED INDEX IDX_V1
ON Sales.vOrders (OrderDate, ProductID);
GO
‐‐This query can use the indexed view even though the view is
‐‐not specified in the FROM clause.
SELECT SUM(UnitPrice*OrderQty*(1.00‐UnitPriceDiscount)) AS Rev,
OrderDate, ProductID
FROM Sales.SalesOrderDetail AS od
JOIN Sales.SalesOrderHeader AS o ON od.SalesOrderID=o.SalesOrderID
AND ProductID BETWEEN 700 and 800
AND OrderDate >= CONVERT(datetime,'05/01/2002',101)
GROUP BY OrderDate, ProductID
ORDER BY Rev DESC;
GO
‐‐This query can use the above indexed view.
SELECT OrderDate, SUM(UnitPrice*OrderQty*(1.00‐UnitPriceDiscount)) AS Rev
FROM Sales.SalesOrderDetail AS od
JOIN Sales.SalesOrderHeader AS o ON od.SalesOrderID=o.SalesOrderID
AND DATEPART(mm,OrderDate)= 3
AND DATEPART(yy,OrderDate) = 2002
GROUP BY OrderDate
ORDER BY OrderDate ASC;
GO
See Also
CREATE INDEX ﴾Transact‐SQL﴿
SET ANSI_NULLS ﴾Transact‐SQL﴿
SET ANSI_PADDING ﴾Transact‐SQL﴿
SET ANSI_WARNINGS ﴾Transact‐SQL﴿
SET ARITHABORT ﴾Transact‐SQL﴿
SET CONCAT_NULL_YIELDS_NULL ﴾Transact‐SQL﴿
SET NUMERIC_ROUNDABORT ﴾Transact‐SQL﴿
SET QUOTED_IDENTIFIER ﴾Transact‐SQL﴿
© 2016 Microsoft
To focus, simplify, and customize the perception each user has of the database.
As a security mechanism by allowing users to access data through the view, without
granting the users permissions to directly access the underlying base tables.
To provide a backward compatible interface to emulate a table whose schema has changed.
Applies to: SQL Server ﴾SQL Server 2008 through current version﴿, Azure SQL Database.
Syntax
CREATE VIEW [ schema_name . ] view_name [ (column [ ,...n ] ) ]
[ WITH <view_attribute> [ ,...n ] ]
AS select_statement
[ WITH CHECK OPTION ]
[ ; ]
<view_attribute> ::=
{
[ ENCRYPTION ]
[ SCHEMABINDING ]
[ VIEW_METADATA ]
}
Arguments
schema_name
Is the name of the schema to which the view belongs.
view_name
Is the name of the view. View names must follow the rules for identifiers. Specifying the
view owner name is optional.
column
Is the name to be used for a column in a view. A column name is required only when a
column is derived from an arithmetic expression, a function, or a constant; when two or
more columns may otherwise have the same name, typically because of a join; or when a
column in a view is specified a name different from that of the column from which it is
derived. Column names can also be assigned in the SELECT statement.
If column is not specified, the view columns acquire the same names as the columns in
the SELECT statement.
Note
In the columns for the view, the permissions for a column name apply across a
CREATE VIEW or ALTER VIEW statement, regardless of the source of the underlying
data. For example, if permissions are granted on the SalesOrderID column in a
CREATE VIEW statement, an ALTER VIEW statement can name the SalesOrderID
column with a different column name, such as OrderRef, and still have the
permissions associated with the view using SalesOrderID.
AS
Specifies the actions the view is to perform.
select_statement
Is the SELECT statement that defines the view. The statement can use more than one
table and other views. Appropriate permissions are required to select from the objects
referenced in the SELECT clause of the view that is created.
A view does not have to be a simple subset of the rows and columns of one particular
table. A view can be created that uses more than one table or other views with a SELECT
clause of any complexity.
In an indexed view definition, the SELECT statement must be a single table statement or a
multitable JOIN with optional aggregation.
An ORDER BY clause, unless there is also a TOP clause in the select list of the
SELECT statement
Important
The ORDER BY clause is used only to determine the rows that are returned by
the TOP or OFFSET clause in the view definition. The ORDER BY clause does not
guarantee ordered results when the view is queried, unless ORDER BY is also
specified in the query itself.
Because select_statement uses the SELECT statement, it is valid to use <join_hint> and
<table_hint> hints as specified in the FROM clause. For more information, see FROM
﴾Transact‐SQL﴿ and SELECT ﴾Transact‐SQL﴿.
Functions and multiple SELECT statements separated by UNION or UNION ALL can be
used in select_statement.
CHECK OPTION
Forces all data modification statements executed against the view to follow the criteria
set within select_statement. When a row is modified through a view, the WITH CHECK
OPTION makes sure the data remains visible through the view after the modification is
committed.
Note
Any updates performed directly to a view's underlying tables are not verified against
the view, even if CHECK OPTION is specified.
ENCRYPTION
Encrypts the entries in sys.syscomments that contain the text of the CREATE VIEW
statement. Using WITH ENCRYPTION prevents the view from being published as part of
SQL Server replication.
SCHEMABINDING
Binds the view to the schema of the underlying table or tables. When SCHEMABINDING
is specified, the base table or tables cannot be modified in a way that would affect the
view definition. The view definition itself must first be modified or dropped to remove
dependencies on the table that is to be modified. When you use SCHEMABINDING, the
select_statement must include the two‐part names ﴾schema.object﴿ of tables, views, or
user‐defined functions that are referenced. All referenced objects must be in the same
database.
Views or tables that participate in a view created with the SCHEMABINDING clause
cannot be dropped unless that view is dropped or changed so that it no longer has
schema binding. Otherwise, the Database Engine raises an error. Also, executing ALTER
TABLE statements on tables that participate in views that have schema binding fail when
these statements affect the view definition.
VIEW_METADATA
Specifies that the instance of SQL Server will return to the DB‐Library, ODBC, and OLE DB
APIs the metadata information about the view, instead of the base table or tables, when
browse‐mode metadata is being requested for a query that references the view. Browse‐
mode metadata is additional metadata that the instance of SQL Server returns to these
client‐side APIs. This metadata enables the client‐side APIs to implement updatable
client‐side cursors. Browse‐mode metadata includes information about the base table
that the columns in the result set belong to.
For views created with VIEW_METADATA, the browse‐mode metadata returns the view
name and not the base table names when it describes columns from the view in the
result set.
When a view is created by using WITH VIEW_METADATA, all its columns, except a
timestamp column, are updatable if the view has INSTEAD OF INSERT or INSTEAD OF
UPDATE triggers. For more information about updatable views, see Remarks.
Remarks
A view can be created only in the current database. The CREATE VIEW must be the first
statement in a query batch. A view can have a maximum of 1,024 columns.
When querying through a view, the Database Engine checks to make sure that all the database
objects referenced anywhere in the statement exist and that they are valid in the context of the
statement, and that data modification statements do not violate any data integrity rules. A check
that fails returns an error message. A successful check translates the action into an action
against the underlying table or tables.
If a view depends on a table or view that was dropped, the Database Engine produces an error
message when anyone tries to use the view. If a new table or view is created and the table
structure does not change from the previous base table to replace the one dropped, the view
again becomes usable. If the new table or view structure changes, the view must be dropped
and re‐created.
If a view is not created with the SCHEMABINDING clause, sp_refreshview should be run when
changes are made to the objects underlying the view that affect the definition of the view.
Otherwise, the view might produce unexpected results when it is queried.
When a view is created, information about the view is stored in the following catalog views:
sys.views, sys.columns, and sys.sql_expression_dependencies. The text of the CREATE VIEW
statement is stored in the sys.sql_modules catalog view.
A query that uses an index on a view defined with numeric or float expressions may have a
result that is different from a similar query that does not use the index on the view. This
difference may be caused by rounding errors during INSERT, DELETE, or UPDATE actions on
underlying tables.
The Database Engine saves the settings of SET QUOTED_IDENTIFIER and SET ANSI_NULLS when
a view is created. These original settings are used to parse the view when the view is used.
Therefore, any client‐session settings for SET QUOTED_IDENTIFIER and SET ANSI_NULLS do not
affect the view definition when the view is accessed.
Updatable Views
You can modify the data of an underlying base table through a view, as long as the following
conditions are true:
Any modifications, including UPDATE, INSERT, and DELETE statements, must reference
columns from only one base table.
The columns being modified in the view must directly reference the underlying data in
the table columns. The columns cannot be derived in any other way, such as through the
following:
TOP is not used anywhere in the select_statement of the view together with the WITH
CHECK OPTION clause.
The previous restrictions apply to any subqueries in the FROM clause of the view, just as they
apply to the view itself. Generally, the Database Engine must be able to unambiguously trace
modifications from the view definition to one base table. For more information, see Modify Data
Through a View.
If the previous restrictions prevent you from modifying data directly through a view, consider
the following options:
INSTEAD OF Triggers
INSTEAD OF triggers can be created on a view to make a view updatable. The INSTEAD
OF trigger is executed instead of the data modification statement on which the trigger is
defined. This trigger lets the user specify the set of actions that must happen to process
the data modification statement. Therefore, if an INSTEAD OF trigger exists for a view on
a specific data modification statement ﴾INSERT, UPDATE, or DELETE﴿, the corresponding
view is updatable through that statement. For more information about INSTEAD OF
triggers, see DML Triggers.
Partitioned Views
If the view is a partitioned view, the view is updatable, subject to certain restrictions.
When it is needed, the Database Engine distinguishes local partitioned views as the views
in which all participating tables and the view are on the same instance of SQL Server, and
distributed partitioned views as the views in which at least one of the tables in the view
resides on a different or remote server.
Partitioned Views
A partitioned view is a view defined by a UNION ALL of member tables structured in the same
way, but stored separately as multiple tables in either the same instance of SQL Server or in a
group of autonomous instances of SQL Server servers, called federated database servers.
Note
The preferred method for partitioning data local to one server is through partitioned tables.
For more information, see Partitioned Tables and Indexes.
In designing a partitioning scheme, it must be clear what data belongs to each partition. For
example, the data for the Customers table is distributed in three member tables in three server
locations: Customers_33 on Server1, Customers_66 on Server2, and Customers_99 on
Server3.
SELECT <select_list1>
FROM T1
UNION ALL
SELECT <select_list2>
FROM T2
UNION ALL
...
SELECT <select_listn>
FROM Tn;
All columns in the member tables should be selected in the column list of the view
definition.
The columns in the same ordinal position of each select list should be of the
same type, including collations. It is not sufficient for the columns to be implicitly
convertible types, as is generally the case for UNION.
Also, at least one column ﴾for example <col>﴿ must appear in all the select lists in
the same ordinal position. This <col> should be defined in a way that the member
tables T1, ..., Tn have CHECK constraints C1, ..., Cn defined on <col>,
respectively.
C1 ::= < simple_interval > [ OR < simple_interval > OR ...]
< simple_interval > :: =
< col > { < | > | <= | >= | = < value >}
| < col > BETWEEN < value1 > AND < value2 >
| < col > IN ( value_list )
| < col > { > | >= } < value1 > AND
< col > { < | <= } < value2 >
The constraints should be in such a way that any specified value of <col> can
satisfy, at most, one of the constraints C1, ..., Cn so that the constraints
should form a set of disjointed or nonoverlapping intervals. The column <col> on
which the disjointed constraints are defined is called the partitioning column.
Note that the partitioning column may have different names in the underlying
tables. The constraints should be in an enabled and trusted state for them to meet
the previously mentioned conditions of the partitioning column. If the constraints
are disabled, re‐enable constraint checking by using the CHECK CONSTRAINT
constraint_name option of ALTER TABLE, and using the WITH CHECK option to
validate them.
{ [col < 10], [col between 11 and 20] , [col > 20] }
{ [col between 11 and 20], [col between 21 and 30], [col between 31 and 100
The same column cannot be used multiple times in the select list.
2. Partitioning column
If there is more than one constraint on the same column in a member table, the
Database Engine ignores all the constraints and does not consider them when
determining whether the view is a partitioned view. To meet the conditions of the
partitioned view, there should be only one partitioning constraint on the
partitioning column.
The tables can be either local tables or tables from other computers that are
running SQL Server that are referenced either through a four‐part name or an
OPENDATASOURCE‐ or OPENROWSET‐based name. The OPENDATASOURCE and
OPENROWSET syntax can specify a table name, but not a pass‐through query. For
more information, see OPENDATASOURCE ﴾Transact‐SQL﴿ and OPENROWSET
﴾Transact‐SQL﴿.
If one or more of the member tables are remote, the view is called distributed
partitioned view, and additional conditions apply. They are described later in this
section.
The same table cannot appear two times in the set of tables that are being
combined with the UNION ALL statement.
The member tables cannot have indexes created on computed columns in the
table.
The member tables should have all PRIMARY KEY constraints on the same number
of columns.
All member tables in the view should have the same ANSI padding setting. This
can be set by using either the user options option in sp_configure or the SET
statement.
The INSERT statement must supply values for all the columns in the view, even if the
underlying member tables have a DEFAULT constraint for those columns or if they allow
for null values. For those member table columns that have DEFAULT definitions, the
statements cannot explicitly use the keyword DEFAULT.
The value being inserted into the partitioning column should satisfy at least one of the
underlying constraints; otherwise, the insert action will fail with a constraint violation.
UPDATE statements cannot specify the DEFAULT keyword as a value in the SET clause,
even if the column has a DEFAULT value defined in the corresponding member table.
Columns in the view that are an identity column in one or more of the member tables
cannot be modified by using an INSERT or UPDATE statement.
If one of the member tables contains a timestamp column, the data cannot be modified
by using an INSERT or UPDATE statement.
INSERT, UPDATE, and DELETE actions against a partitioned view are not allowed if there
is a self‐join with the same view or with any of the member tables in the statement.
Bulk importing data into a partitioned view is unsupported by bcp or the BULK INSERT
and INSERT ... SELECT * FROM OPENROWSET﴾BULK...﴿ statements. However, you can
insert multiple rows into a partitioned view by using the INSERT statement.
Note
To update a partitioned view, the user must have INSERT, UPDATE, and DELETE
permissions on the member tables.
A distributed transaction will be started to guarantee atomicity across all nodes affected
by the update.
The XACT_ABORT SET option should be set to ON for INSERT, UPDATE, or DELETE
statements to work.
Any columns in remote tables of type smallmoney that are referenced in a partitioned
view are mapped as money. Therefore, the corresponding columns ﴾in the same ordinal
position in the select list﴿ in the local tables must also be of type money.
Under database compatibility level 110 and higher, any columns in remote tables of type
smalldatetime that are referenced in a partitioned view are mapped as smalldatetime.
Corresponding columns ﴾in the same ordinal position in the select list﴿ in the local tables
must be smalldatetime. This is a change in behavior from earlier versions of SQL Server
in which any columns in remote tables of type smalldatetime that are referenced in a
partitioned view are mapped as datetime and corresponding columns in local tables
must be of type datetime. For more information, see ALTER DATABASE Compatibility
Level ﴾Transact‐SQL﴿.
Any linked server in the partitioned view cannot be a loopback linked server. This is a
linked server that points to the same instance of SQL Server.
The setting of the SET ROWCOUNT option is ignored for INSERT, UPDATE, and DELETE actions
that involve updatable partitioned views and remote tables.
When the member tables and partitioned view definition are in place, the SQL Server query
optimizer builds intelligent plans that use queries efficiently to access data from member tables.
With the CHECK constraint definitions, the query processor maps the distribution of key values
across the member tables. When a user issues a query, the query processor compares the map
to the values specified in the WHERE clause, and builds an execution plan with a minimal
amount of data transfer between member servers. Therefore, although some member tables
may be located in remote servers, the instance of SQL Server resolves distributed queries so that
the amount of distributed data that has to be transferred is minimal.
If the underlying tables are involved in merge replication or transactional replication with
updating subscriptions, the uniqueidentifier column should also be included in the
select list.
Any INSERT actions into the partitioned view must provide a NEWID﴾﴿ value for the
uniqueidentifier column. Any UPDATE actions against the uniqueidentifier column
must supply NEWID﴾﴿ as the value because the DEFAULT keyword cannot be used.
The replication of updates made by using the view is the same as when tables are
replicated in two different databases: the tables are served by different replication agents
and the order of the updates is not guaranteed.
Permissions
Requires CREATE VIEW permission in the database and ALTER permission on the schema in
which the view is being created.
Examples
USE AdventureWorks2012 ;
GO
IF OBJECT_ID ('hiredate_view', 'V') IS NOT NULL
DROP VIEW hiredate_view ;
GO
CREATE VIEW hiredate_view
AS
SELECT p.FirstName, p.LastName, e.BusinessEntityID, e.HireDate
FROM HumanResources.Employee e
JOIN Person.Person AS p ON e.BusinessEntityID = p.BusinessEntityID ;
GO
USE AdventureWorks2012 ;
GO
IF OBJECT_ID ('Purchasing.PurchaseOrderReject', 'V') IS NOT NULL
DROP VIEW Purchasing.PurchaseOrderReject ;
GO
CREATE VIEW Purchasing.PurchaseOrderReject
WITH ENCRYPTION
AS
SELECT PurchaseOrderID, ReceivedQty, RejectedQty,
RejectedQty / ReceivedQty AS RejectRatio, DueDate
FROM Purchasing.PurchaseOrderDetail
WHERE RejectedQty / ReceivedQty > 0
AND DueDate > CONVERT(DATETIME,'20010630',101) ;
GO
USE AdventureWorks2012 ;
GO
IF OBJECT_ID ('dbo.SeattleOnly', 'V') IS NOT NULL
DROP VIEW dbo.SeattleOnly ;
GO
CREATE VIEW dbo.SeattleOnly
AS
SELECT p.LastName, p.FirstName, e.JobTitle, a.City, sp.StateProvinceCode
FROM HumanResources.Employee e
INNER JOIN Person.Person p
ON p.BusinessEntityID = e.BusinessEntityID
INNER JOIN Person.BusinessEntityAddress bea
ON bea.BusinessEntityID = e.BusinessEntityID
INNER JOIN Person.Address a
ON a.AddressID = bea.AddressID
INNER JOIN Person.StateProvince sp
ON sp.StateProvinceID = a.StateProvinceID
WHERE a.City = 'Seattle'
WITH CHECK OPTION ;
GO
USE AdventureWorks2012 ;
GO
IF OBJECT_ID ('Sales.SalesPersonPerform', 'V') IS NOT NULL
DROP VIEW Sales.SalesPersonPerform ;
GO
CREATE VIEW Sales.SalesPersonPerform
AS
SELECT TOP (100) SalesPersonID, SUM(TotalDue) AS TotalSales
FROM Sales.SalesOrderHeader
WHERE OrderDate > CONVERT(DATETIME,'20001231',101)
GROUP BY SalesPersonID;
GO
See Also
Reference
ALTER TABLE ﴾Transact‐SQL﴿
ALTER VIEW ﴾Transact‐SQL﴿
DELETE ﴾Transact‐SQL﴿
DROP VIEW ﴾Transact‐SQL﴿
INSERT ﴾Transact‐SQL﴿
sys.dm_sql_referenced_entities ﴾Transact‐SQL﴿
sys.dm_sql_referencing_entities ﴾Transact‐SQL﴿
sp_help ﴾Transact‐SQL﴿
sp_helptext ﴾Transact‐SQL﴿
sp_refreshview ﴾Transact‐SQL﴿
sp_rename ﴾Transact‐SQL﴿
sys.views ﴾Transact‐SQL﴿
UPDATE ﴾Transact‐SQL﴿
EVENTDATA ﴾Transact‐SQL﴿
Concepts
Create a Stored Procedure
© 2016 Microsoft
You can use an xml type column to create views. The following example creates a view in which
the value from an xml type column is retrieved using the value﴾﴿ method of the xml data type.
‐‐ Create the table.
CREATE TABLE T (
ProductID int primary key,
CatalogDescription xml)
GO
‐‐ Insert sample data.
INSERT INTO T values(1,'<ProductDescription ProductID="1" ProductName="SomeName" />')
GO
‐‐ Create view (note the value() method used to retrieve ProductName
‐‐ attribute value from the XML).
CREATE VIEW MyView AS
SELECT ProductID,
CatalogDescription.value('(/ProductDescription/@ProductName)[1]', 'varchar(40)'
FROM T
GO
SELECT *
FROM MyView
ProductID PName
‐‐‐‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐‐‐‐‐
1 SomeName
Note the following points about using the xml data type to create views:
The xml data type can be created in a materialized view. The materialized view cannot be
based on an xml data type method. However, it can be cast to an XML schema collection
that is different from the xml type column in the base table.
SQL predicates running against the view will not be pushed into the XQuery of the view
definition.
© 2016 Microsoft
Modify Views
Modify Views
SQL Server 2014
After you define a view, you can modify its definition in SQL Server 2014 without dropping and re‐
creating the view by using SQL Server Management Studio or Transact‐SQL.
In This Topic
Security
Using Transact‐SQL
If a view currently used is modified by using ALTER VIEW, the Database Engine takes
an exclusive schema lock on the view. When the lock is granted, and there are no
active users of the view, the Database Engine deletes all copies of the view from the
procedure cache. Existing plans referencing the view remain in the cache but are
recompiled when invoked.
ALTER VIEW can be applied to indexed views; however, ALTER VIEW unconditionally
drops all indexes on the view.
Security
Permissions
To execute ALTER VIEW, at a minimum, ALTER permission on OBJECT is required.
To modify a view
1. In Object Explorer, click the plus sign next to the database where your view is located
and then click the plus sign next to the Views folder.
3. In the diagram pane of the query designer, make changes to the view in one or more of
the following ways:
a. Select or clear the check boxes of any elements you wish to add or remove.
b. Right‐click within the diagram pane, select Add Table…, and then select the
additional columns you want to add to the view from the Add Table dialog box.
c. Right‐click the title bar of the table you wish to remove and select Remove.
To modify a view
3. Copy and paste the following example into the query window and click Execute. The
example first creates a view and then modifies the view by using ALTER VIEW. A WHERE
clause is added to the view definition.
USE AdventureWorks2012 ;
GO
‐‐ Create a view.
CREATE VIEW HumanResources.EmployeeHireDate
AS
SELECT p.FirstName, p.LastName, e.HireDate
FROM HumanResources.Employee AS e JOIN Person.Person AS p
ON e.BusinessEntityID = p.BusinessEntityID ;
‐‐ Modify the view by adding a WHERE clause to limit the rows returned.
ALTER VIEW HumanResources.EmployeeHireDate
AS
SELECT p.FirstName, p.LastName, e.HireDate
FROM HumanResources.Employee AS e JOIN Person.Person AS p
ON e.BusinessEntityID = p.BusinessEntityID
WHERE HireDate < CONVERT(DATETIME,'20020101',101) ;
GO
© 2016 Microsoft
THIS TOPIC APPLIES TO: SQL Server Azure SQL Database Azure SQL Data
Warehouse Parallel Data Warehouse
Modifies a previously created view. This includes an indexed view. ALTER VIEW does not affect
dependent stored procedures or triggers and does not change permissions.
Syntax
ALTER VIEW [ schema_name . ] view_name [ ( column [ ,...n ] ) ]
[ WITH <view_attribute> [ ,...n ] ]
AS select_statement
[ WITH CHECK OPTION ] [ ; ]
<view_attribute> ::=
{
[ ENCRYPTION ]
[ SCHEMABINDING ]
[ VIEW_METADATA ]
}
Arguments
schema_name
Is the name of the schema to which the view belongs.
view_name
Is the view to change.
column
Is the name of one or more columns, separated by commas, that are to be part of the
specified view.
Important
Column permissions are maintained only when columns have the same name before
and after ALTER VIEW is performed.
Note
In the columns for the view, the permissions for a column name apply across a
CREATE VIEW or ALTER VIEW statement, regardless of the source of the underlying
data. For example, if permissions are granted on the SalesOrderID column in a
CREATE VIEW statement, an ALTER VIEW statement can rename the SalesOrderID
column, such as to OrderRef, and still have the permissions associated with the view
using SalesOrderID.
ENCRYPTION
Applies to: SQL Server 2008 through SQL Server 2016.
Encrypts the entries in sys.syscomments that contain the text of the ALTER VIEW
statement. WITH ENCRYPTION prevents the view from being published as part of SQL
Server replication.
SCHEMABINDING
Binds the view to the schema of the underlying table or tables. When SCHEMABINDING
is specified, the base tables cannot be modified in a way that would affect the view
definition. The view definition itself must first be modified or dropped to remove
dependencies on the table to be modified. When you use SCHEMABINDING, the
select_statement must include the two‐part names ﴾schema.object﴿ of tables, views, or
user‐defined functions that are referenced. All referenced objects must be in the same
database.
Views or tables that participate in a view created with the SCHEMABINDING clause
cannot be dropped, unless that view is dropped or changed so that it no longer has
schema binding. Otherwise, the Database Engine raises an error. Also, executing ALTER
TABLE statements on tables that participate in views that have schema binding fail if
these statements affect the view definition.
VIEW_METADATA
Specifies that the instance of SQL Server will return to the DB‐Library, ODBC, and OLE DB
APIs the metadata information about the view, instead of the base table or tables, when
browse‐mode metadata is being requested for a query that references the view. Browse‐
mode metadata is additional metadata that the instance of Database Engine returns to
the client‐side DB‐Library, ODBC, and OLE DB APIs. This metadata enables the client‐side
APIs to implement updatable client‐side cursors. Browse‐mode metadata includes
information about the base table that the columns in the result set belong to.
For views created with VIEW_METADATA, the browse‐mode metadata returns the view
name and not the base table names when it describes columns from the view in the
result set.
When a view is created by using WITH VIEW_METADATA, all its columns, except a
timestamp column, are updatable if the view has INSERT or UPDATE INSTEAD OF
triggers. For more information, see the Remarks section in CREATE VIEW ﴾Transact‐SQL﴿.
AS
Are the actions the view is to take.
select_statement
Is the SELECT statement that defines the view.
Remarks
For more information about ALTER VIEW, see Remarks in CREATE VIEW ﴾Transact‐SQL﴿.
Note
If the previous view definition was created by using WITH ENCRYPTION or CHECK OPTION,
these options are enabled only if they are included in ALTER VIEW.
If a view currently used is modified by using ALTER VIEW, the Database Engine takes an
exclusive schema lock on the view. When the lock is granted, and there are no active users of
the view, the Database Engine deletes all copies of the view from the procedure cache. Existing
plans referencing the view remain in the cache but are recompiled when invoked.
ALTER VIEW can be applied to indexed views; however, ALTER VIEW unconditionally drops all
indexes on the view.
Permissions
To execute ALTER VIEW, at a minimum, ALTER permission on OBJECT is required.
Examples
The following example creates a view that contains all employees and their hire dates called
EmployeeHireDate. Permissions are granted to the view, but requirements are changed to
select employees whose hire dates fall before a certain date. Then, ALTER VIEW is used to
replace the view.
USE AdventureWorks2012 ;
GO
CREATE VIEW HumanResources.EmployeeHireDate
AS
SELECT p.FirstName, p.LastName, e.HireDate
FROM HumanResources.Employee AS e JOIN Person.Person AS p
ON e.BusinessEntityID = p.BusinessEntityID ;
GO
The view must be changed to include only the employees that were hired before 2002. If ALTER
VIEW is not used, but instead the view is dropped and re‐created, the previously used GRANT
statement and any other statements that deal with permissions pertaining to this view must be
re‐entered.
ALTER VIEW HumanResources.EmployeeHireDate
AS
SELECT p.FirstName, p.LastName, e.HireDate
FROM HumanResources.Employee AS e JOIN Person.Person AS p
ON e.BusinessEntityID = p.BusinessEntityID
WHERE HireDate < CONVERT(DATETIME,'20020101',101) ;
GO
See Also
CREATE TABLE ﴾Transact‐SQL﴿
CREATE VIEW ﴾Transact‐SQL﴿
DROP VIEW ﴾Transact‐SQL﴿
Create a Stored Procedure
SELECT ﴾Transact‐SQL﴿
EVENTDATA ﴾Transact‐SQL﴿
Make Schema Changes on Publication Databases
© 2016 Microsoft
You can modify the data of an underlying base table in SQL Server 2014 by using SQL Server
Management Studio or Transact‐SQL.
In This Topic
Security
Using Transact‐SQL
Permissions
Requires UPDATE, INSERT, or DELETE permissions on the target table, depending on the
action being performed.
1. In Object Explorer, expand the database that contains the view and then expand Views.
3. You may need to modify the SELECT statement in the SQL pane to return the rows to be
modified.
4. In the Results pane, locate the row to be changed or deleted. To delete the row, right‐
click the row and select Delete. To change data in one or more columns, modify the data
in the column.
Important
You cannot delete a row if the view references more than one base table. You can
only update columns that belong to a single base table.
5. To insert a row, scroll down to the end of the rows and insert the new values.
Important
You cannot insert a row if the view references more than one base table.
Using Transact-SQL
3. Copy and paste the following example into the query window and click Execute. This
example changes the value in the StartDate and EndDate columns for a specific
employee by referencing columns in the view
HumanResources.vEmployeeDepartmentHistory. This view returns values from two
tables. This statement succeeds because the columns being modified are from only one
of the base tables.
USE AdventureWorks2012 ;
GO
UPDATE HumanResources.vEmployeeDepartmentHistory
SET StartDate = '20110203', EndDate = GETDATE()
WHERE LastName = N'Smith' AND FirstName = 'Samantha';
GO
3. Copy and paste the following example into the query window and click Execute. The
example inserts a new row into the base table HumanResouces.Department by
specifying the relevant columns from the view
HumanResources.vEmployeeDepartmentHistory. The statement succeeds because
only columns from a single base table are specified and the other columns in the base
table have default values.
USE AdventureWorks2012 ;
GO
INSERT INTO HumanResources.vEmployeeDepartmentHistory (Department, GroupName)
VALUES ('MyDepartment', 'MyGroup');
GO
© 2016 Microsoft
UPDATE ﴾Transact‐SQL﴿
Changes existing data in a table or view in SQL Server 2014. For examples, see Examples.
Applies to: SQL Server ﴾SQL Server 2008 through current version﴿, Azure SQL Database.
Syntax
Transact‐SQL
[ WITH <common_table_expression> [...n] ]
UPDATE
[ TOP ( expression ) [ PERCENT ] ]
{ { table_alias | <object> | rowset_function_limited
[ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
}
| @table_variable
}
SET
{ column_name = { expression | DEFAULT | NULL }
| { udt_column_name.{ { property_name = expression
| field_name = expression }
| method_name ( argument [ ,...n ] )
}
}
| column_name { .WRITE ( expression , @Offset , @Length ) }
| @variable = expression
| @variable = column = expression
| column_name { += | ‐= | *= | /= | %= | &= | ^= | |= } expression
| @variable { += | ‐= | *= | /= | %= | &= | ^= | |= } expression
| @variable = column { += | ‐= | *= | /= | %= | &= | ^= | |= } expression
} [ ,...n ]
[ <OUTPUT Clause> ]
[ FROM{ <table_source> } [ ,...n ] ]
[ WHERE { <search_condition>
| { [ CURRENT OF
{ { [ GLOBAL ] cursor_name }
| cursor_variable_name
}
]
}
}
]
[ OPTION ( <query_hint> [ ,...n ] ) ]
[ ; ]
<object> ::=
{
[ server_name . database_name . schema_name .
| database_name .[ schema_name ] .
| schema_name .
]
table_or_view_name}
Arguments
WITH <common_table_expression>
Specifies the temporary named result set or view, also known as common table
expression ﴾CTE﴿, defined within the scope of the UPDATE statement. The CTE result set is
derived from a simple query and is referenced by UPDATE statement.
Common table expressions can also be used with the SELECT, INSERT, DELETE, and
CREATE VIEW statements. For more information, see WITH common_table_expression
﴾Transact‐SQL﴿.
The rows referenced in the TOP expression used with INSERT, UPDATE, or DELETE are not
arranged in any order.
Parentheses delimiting expression in TOP are required in INSERT, UPDATE, and DELETE
statements. For more information, see TOP ﴾Transact‐SQL﴿.
table_alias
The alias specified in the FROM clause representing the table or view from which the
rows are to be updated.
server_name
Is the name of the server ﴾using a linked server name or the OPENDATASOURCE function
as the server name﴿ on which the table or view is located. If server_name is specified,
database_name and schema_name are required.
database_name
Is the name of the database.
schema_name
Is the name of the schema to which the table or view belongs.
table_or view_name
Is the name of the table or view from which the rows are to be updated. The view
referenced by table_or_view_name must be updatable and reference exactly one base
table in the FROM clause of the view. For more information about updatable views, see
CREATE VIEW ﴾Transact‐SQL﴿.
rowset_function_limited
Is either the OPENQUERY or OPENROWSET function, subject to provider capabilities.
WITH ﴾ <Table_Hint_Limited> ﴿
Specifies one or more table hints that are allowed for a target table. The WITH keyword
and the parentheses are required. NOLOCK and READUNCOMMITTED are not allowed.
For information about table hints, see Table Hints ﴾Transact‐SQL﴿.
@table_variable
Specifies a table variable as a table source.
SET
Specifies the list of column or variable names to be updated.
column_name
Is a column that contains the data to be changed. column_name must exist in table_or
view_name. Identity columns cannot be updated.
expression
Is a variable, literal value, expression, or a subselect statement ﴾enclosed with
parentheses﴿ that returns a single value. The value returned by expression replaces the
existing value in column_name or @variable.
Note
When referencing the Unicode character data types nchar, nvarchar, and ntext,
'expression' should be prefixed with the capital letter 'N'. If 'N' is not specified, SQL
Server converts the string to the code page that corresponds to the default collation
of the database or column. Any characters not found in this code page are lost.
DEFAULT
Specifies that the default value defined for the column is to replace the existing value in
the column. This can also be used to change the column to NULL if the column has no
default and is defined to allow null values.
{ += | ‐= | *= | /= | %= | &= | ^= | |= }
Compound assignment operator:
udt_column_name
Is a user‐defined type column.
property_name | field_name
Is a public property or public data member of a user‐defined type.
.WRITE ﴾expression,@Offset,@Length﴿
Specifies that a section of the value of column_name is to be modified. expression
replaces @Length units starting from @Offset of column_name. Only columns of
varchar﴾max﴿, nvarchar﴾max﴿, or varbinary﴾max﴿ can be specified with this clause.
column_name cannot be NULL and cannot be qualified with a table name or table alias.
@Offset is the starting point in the value of column_name at which expression is written.
@Offset is a zero‐based ordinal position, is bigint, and cannot be a negative number. If
@Offset is NULL, the update operation appends expression at the end of the existing
column_name value and @Length is ignored. If @Offset is greater than the length of the
column_name value, the Database Engine returns an error. If @Offset plus @Length
exceeds the end of the underlying value in the column, the deletion occurs up to the last
character of the value. If @Offset plus LEN﴾expression﴿ is greater than the underlying
declared size, an error is raised.
@Length is the length of the section in the column, starting from @Offset, that is
replaced by expression. @Length is bigint and cannot be a negative number. If @Length
is NULL, the update operation removes all data from @Offset to the end of the
column_name value.
@ variable
Is a declared variable that is set to the value returned by expression.
SET @variable = column = expression sets the variable to the same value as the column.
This differs from SET @variable = column, column = expression, which sets the variable to
the pre‐update value of the column.
<OUTPUT_Clause>
Returns updated data or expressions based on it as part of the UPDATE operation. The
OUTPUT clause is not supported in any DML statements that target remote tables or
views. For more information, see OUTPUT Clause ﴾Transact‐SQL﴿.
FROM <table_source>
Specifies that a table, view, or derived table source is used to provide the criteria for the
update operation. For more information, see FROM ﴾Transact‐SQL﴿.
If the object being updated is the same as the object in the FROM clause and there is
only one reference to the object in the FROM clause, an object alias may or may not be
specified. If the object being updated appears more than one time in the FROM clause,
one, and only one, reference to the object must not specify a table alias. All other
references to the object in the FROM clause must include an object alias.
Note
WHERE
Specifies the conditions that limit the rows that are updated. There are two forms of
update based on which form of the WHERE clause is used:
Positioned updates use the CURRENT OF clause to specify a cursor. The update
operation occurs at the current position of the cursor.
<search_condition>
Specifies the condition to be met for the rows to be updated. The search condition can
also be the condition upon which a join is based. There is no limit to the number of
predicates that can be included in a search condition. For more information about
predicates and search conditions, see Search Condition ﴾Transact‐SQL﴿.
CURRENT OF
Specifies that the update is performed at the current position of the specified cursor.
A positioned update using a WHERE CURRENT OF clause updates the single row at the
current position of the cursor. This can be more accurate than a searched update that
uses a WHERE <search_condition> clause to qualify the rows to be updated. A searched
update modifies multiple rows when the search condition does not uniquely identify a
single row.
GLOBAL
Specifies that cursor_name refers to a global cursor.
cursor_name
Is the name of the open cursor from which the fetch should be made. If both a global
and a local cursor with the name cursor_name exist, this argument refers to the global
cursor if GLOBAL is specified; otherwise, it refers to the local cursor. The cursor must
allow updates.
cursor_variable_name
Is the name of a cursor variable. cursor_variable_name must reference a cursor that allows
updates.
Best Practices
Use the @@ROWCOUNT function to return the number of inserted rows to the client
application. For more information, see @@ROWCOUNT ﴾Transact‐SQL﴿.
Variable names can be used in UPDATE statements to show the old and new values affected, but
this should be used only when the UPDATE statement affects a single record. If the UPDATE
statement affects multiple records, to return the old and new values for each record, use the
OUTPUT clause.
Use caution when specifying the FROM clause to provide the criteria for the update operation.
The results of an UPDATE statement are undefined if the statement includes a FROM clause that
is not specified in such a way that only one value is available for each column occurrence that is
updated, that is if the UPDATE statement is not deterministic. For example, in the UPDATE
statement in the following script, both rows in Table1 meet the qualifications of the FROM
clause in the UPDATE statement; but it is undefined which row from Table1 is used to update
the row in Table2.
USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
(ColA int NOT NULL, ColB decimal(10,3) NOT NULL);
GO
CREATE TABLE dbo.Table2
(ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES(1, 10.0), (1, 20.0);
INSERT INTO dbo.Table2 VALUES(1, 0.0);
GO
UPDATE dbo.Table2
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2
INNER JOIN dbo.Table1
ON (dbo.Table2.ColA = dbo.Table1.ColA);
GO
SELECT ColA, ColB
FROM dbo.Table2;
The same problem can occur when the FROM and WHERE CURRENT OF clauses are combined.
In the following example, both rows in Table2 meet the qualifications of the FROM clause in the
UPDATE statement. It is undefined which row from Table2 is to be used to update the row in
Table1.
USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
(c1 int PRIMARY KEY NOT NULL, c2 int NOT NULL);
GO
CREATE TABLE dbo.Table2
(d1 int PRIMARY KEY NOT NULL, d2 int NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES (1, 10);
INSERT INTO dbo.Table2 VALUES (1, 20), (2, 30);
GO
DECLARE abc CURSOR LOCAL FOR
SELECT c1, c2
FROM dbo.Table1;
OPEN abc;
FETCH abc;
UPDATE dbo.Table1
SET c2 = c2 + d2
FROM dbo.Table2
WHERE CURRENT OF abc;
GO
SELECT c1, c2 FROM dbo.Table1;
GO
Compatibility Support
Support for use of the READUNCOMMITTED and NOLOCK hints in the FROM clause that apply
to the target table of an UPDATE or DELETE statement will be removed in a future version of
SQL Server. Avoid using these hints in this context in new development work, and plan to
modify applications that currently use them.
Data Types
All char and nchar columns are right‐padded to the defined length.
If ANSI_PADDING is set to OFF, all trailing spaces are removed from data inserted into varchar
and nvarchar columns, except in strings that contain only spaces. These strings are truncated to
an empty string. If ANSI_PADDING is set to ON, trailing spaces are inserted. The Microsoft SQL
Server ODBC driver and OLE DB Provider for SQL Server automatically set ANSI_PADDING ON
for each connection. This can be configured in ODBC data sources or by setting connection
attributes or properties. For more information, see SET ANSI_PADDING ﴾Transact‐SQL﴿.
To replace or modify large blocks of text, ntext, or image data, use WRITETEXT or UPDATETEXT
instead of the UPDATE statement.
If the UPDATE statement could change more than one row while updating both the clustering
key and one or more text, ntext, or image columns, the partial update to these columns is
executed as a full replacement of the values.
Important
The ntext, text, and image data types will be removed in a future version of Microsoft SQL
Server. Avoid using these data types in new development work, and plan to modify
applications that currently use them. Use nvarchar﴾max﴿, varchar﴾max﴿, and varbinary﴾max﴿
instead.
The Database Engine converts a partial update to a full update when the UPDATE statement
causes either of these actions:
Modifies more than one row and also updates the key of a nonunique clustered index to
a nonconstant value.
You cannot use the .WRITE clause to update a NULL column or set the value of column_name to
NULL.
@Offset and @Length are specified in bytes for varbinary and varchar data types and in
characters for the nvarchar data type. The appropriate offsets are computed for double‐byte
character set ﴾DBCS﴿ collations.
For best performance, we recommend that data be inserted or updated in chunk sizes that are
multiples of 8040 bytes.
If the column modified by the .WRITE clause is referenced in an OUTPUT clause, the complete
value of the column, either the before image in deleted.column_name or the after image in
inserted.column_name, is returned to the specified column in the table variable. See example G
that follows.
To achieve the same functionality of .WRITE with other character or binary data types, use the
STUFF ﴾Transact‐SQL﴿.
Supplying a value in a SQL Server system data type, as long as the user‐defined type
supports implicit or explicit conversion from that type. The following example shows how
to update a value in a column of user‐defined type Point, by explicitly converting from a
string.
UPDATE Cities
SET Location = CONVERT(Point, '12.3:46.2')
WHERE Name = 'Anchorage';
UPDATE Cities
SET Location.SetXY(23.5, 23.5)
WHERE Name = 'Anchorage';
Note
Modifying the value of a registered property or public data member of the user‐defined
type. The expression supplying the value must be implicitly convertible to the type of the
property. The following example modifies the value of property X of user‐defined type
Point.
UPDATE Cities
SET Location.X = 23.5
WHERE Name = 'Anchorage';
To modify different properties of the same user‐defined type column, issue multiple
UPDATE statements, or invoke a mutator method of the type.
Error Handling
If an update to a row violates a constraint or rule, violates the NULL setting for the column, or
the new value is an incompatible data type, the statement is canceled, an error is returned, and
no records are updated.
Interoperability
UPDATE statements are allowed in the body of user‐defined functions only if the table being
modified is a table variable.
When an INSTEAD OF trigger is defined on UPDATE actions against a table, the trigger is
running instead of the UPDATE statement. Earlier versions of SQL Server only support AFTER
triggers defined on UPDATE and other data modification statements. The FROM clause cannot
be specified in an UPDATE statement that references, either directly or indirectly, a view with an
INSTEAD OF trigger defined on it. For more information about INSTEAD OF triggers, see CREATE
TRIGGER ﴾Transact‐SQL﴿.
When a common table expression ﴾CTE﴿ is the target of an UPDATE statement, all references to
the CTE in the statement must match. For example, if the CTE is assigned an alias in the FROM
clause, the alias must be used for all other references to the CTE. Unambiguous CTE references
are required because a CTE does not have an object ID, which SQL Server uses to recognize the
implicit relationship between an object and its alias. Without this relationship, the query plan
may produce unexpected join behavior and unintended query results. The following examples
demonstrate correct and incorrect methods of specifying a CTE when the CTE is the target
object of the update operation.
USE tempdb;
GO
‐‐ UPDATE statement with CTE references that are correctly matched.
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);
WITH cte AS (SELECT * FROM @x)
UPDATE x ‐‐ cte is referenced by the alias.
SET Value = y.Value
FROM cte AS x ‐‐ cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID;
SELECT * FROM @x;
GO
‐‐‐‐‐‐ ‐‐‐‐‐
1 100
2 200
(2 row(s) affected)
‐‐ UPDATE statement with CTE references that are incorrectly matched.
USE tempdb;
GO
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);
WITH cte AS (SELECT * FROM @x)
UPDATE cte ‐‐ cte is not referenced by the alias.
SET Value = y.Value
FROM cte AS x ‐‐ cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID;
SELECT * FROM @x;
GO
ID Value
‐‐‐‐‐‐ ‐‐‐‐‐
1 100
2 100
(2 row(s) affected)
Locking Behavior
An UPDATE statement always acquires an exclusive ﴾X﴿ lock on the table it modifies, and holds
that lock until the transaction completes. With an exclusive lock, no other transactions can
modify data. You can specify table hints to override this default behavior for the duration of the
UPDATE statement by specifying another locking method, however, we recommend that hints
be used only as a last resort by experienced developers and database administrators. For more
information, see Table Hints ﴾Transact‐SQL﴿.
Logging Behavior
The UPDATE statement is logged; however, partial updates to large value data types using the
.WRITE clause are minimally logged. For more information, see "Updating Large Value Data
Types" in the earlier section “Data Types”.
Security
Permissions
UPDATE permissions are required on the target table. SELECT permissions are also required for
the table being updated if the UPDATE statement contains a WHERE clause, or if expression in
the SET clause uses a column in the table.
UPDATE permissions default to members of the sysadmin fixed server role, the db_owner and
db_datawriter fixed database roles, and the table owner. Members of the sysadmin, db_owner,
and db_securityadmin roles, and the table owner can transfer permissions to other users.
Examples
Limiting the Rows that Are Updated WHERE • TOP • WITH common table
expression • WHERE CURRENT OF
Specifying Target Objects Other than views • table variables • table aliases
Standard Tables
Overriding the Default Behavior of the Query table hints • query hints
Optimizer by Using Hints
Capturing the Results of the UPDATE OUTPUT clause
Statement
Basic Syntax
Examples in this section demonstrate the basic functionality of the UPDATE statement using the
minimum required syntax.
USE AdventureWorks2012;
GO
UPDATE Person.Address
SET ModifiedDate = GETDATE();
USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL;
GO
USE AdventureWorks2012;
GO
UPDATE Production.Product
SET Color = N'Metallic Red'
WHERE Name LIKE N'Road‐250%' AND Color = N'Red';
GO
USE AdventureWorks2012;
GO
UPDATE Production.Product
SET Color = N'Metallic Red'
WHERE Name LIKE N'Road‐250%' AND Color = N'Red';
GO
If you must use TOP to apply updates in a meaningful chronology, you must use TOP together
with ORDER BY in a subselect statement. The following example updates the vacation hours of
the 10 employees with the earliest hire dates.
UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee
ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;
GO
USE AdventureWorks2012;
GO
WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS
(
SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty,
b.EndDate, 0 AS ComponentLevel
FROM Production.BillOfMaterials AS b
WHERE b.ProductAssemblyID = 800
AND b.EndDate IS NULL
UNION ALL
SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty,
bom.EndDate, ComponentLevel + 1
FROM Production.BillOfMaterials AS bom
INNER JOIN Parts AS p
ON bom.ProductAssemblyID = p.ComponentID
AND bom.EndDate IS NULL
)
UPDATE Production.BillOfMaterials
SET PerAssemblyQty = c.PerAssemblyQty * 2
FROM Production.BillOfMaterials AS c
JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID
WHERE d.ComponentLevel = 0;
USE AdventureWorks2012;
GO
DECLARE complex_cursor CURSOR FOR
SELECT a.BusinessEntityID
FROM HumanResources.EmployeePayHistory AS a
WHERE RateChangeDate <>
(SELECT MAX(RateChangeDate)
FROM HumanResources.EmployeePayHistory AS b
WHERE a.BusinessEntityID = b.BusinessEntityID) ;
OPEN complex_cursor;
FETCH FROM complex_cursor;
UPDATE HumanResources.EmployeePayHistory
SET PayFrequency = 2
WHERE CURRENT OF complex_cursor;
CLOSE complex_cursor;
DEALLOCATE complex_cursor;
GO
USE AdventureWorks2012 ;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2;
GO
The following example uses the compound operator += to append the data ' ‐ tool
malfunction' to the existing value in the column Name for rows that have a ScrapReasonID
between 10 and 12.
USE AdventureWorks2012;
GO
UPDATE Production.ScrapReason
SET Name += ' ‐ tool malfunction'
WHERE ScrapReasonID BETWEEN 10 and 12;
USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD +
(SELECT SUM(so.SubTotal)
FROM Sales.SalesOrderHeader AS so
WHERE so.OrderDate = (SELECT MAX(OrderDate)
FROM Sales.SalesOrderHeader AS so2
WHERE so2.SalesPersonID = so.SalesPersonID)
AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID
GROUP BY so.SalesPersonID);
GO
USE AdventureWorks2012;
GO
UPDATE Production.Location
SET CostRate = DEFAULT
WHERE CostRate > 20.00;
USE AdventureWorks2012;
GO
UPDATE Person.vStateProvinceCountryRegion
SET CountryRegionName = 'United States of America'
WHERE CountryRegionName = 'United States';
USE AdventureWorks2012;
GO
UPDATE sr
SET sr.Name += ' ‐ tool malfunction'
FROM Production.ScrapReason AS sr
JOIN Production.WorkOrder AS wo
ON sr.ScrapReasonID = wo.ScrapReasonID
AND wo.ScrappedQty > 300;
USE AdventureWorks2012;
GO
‐‐ Create the table variable.
DECLARE @MyTableVar table(
EmpID int NOT NULL,
NewVacationHours int,
ModifiedDate datetime);
‐‐ Populate the table variable with employee ID values from HumanResources.Employee.
INSERT INTO @MyTableVar (EmpID)
SELECT BusinessEntityID FROM HumanResources.Employee;
‐‐ Update columns in the table variable.
UPDATE @MyTableVar
SET NewVacationHours = e.VacationHours + 20,
ModifiedDate = GETDATE()
FROM HumanResources.Employee AS e
WHERE e.BusinessEntityID = EmpID;
‐‐ Display the results of the UPDATE statement.
SELECT EmpID, NewVacationHours, ModifiedDate FROM @MyTableVar
ORDER BY EmpID;
GO
USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + SubTotal
FROM Sales.SalesPerson AS sp
JOIN Sales.SalesOrderHeader AS so
ON sp.BusinessEntityID = so.SalesPersonID
AND so.OrderDate = (SELECT MAX(OrderDate)
FROM Sales.SalesOrderHeader
WHERE SalesPersonID = sp.BusinessEntityID);
GO
The previous example assumes that only one sale is recorded for a specified salesperson on a
specific date and that updates are current. If more than one sale for a specified salesperson can
be recorded on the same day, the example shown does not work correctly. The example runs
without error, but each SalesYTD value is updated with only one sale, regardless of how many
sales actually occurred on that day. This is because a single UPDATE statement never updates
the same row two times.
In the situation in which more than one sale for a specified salesperson can occur on the same
day, all the sales for each sales person must be aggregated together within the UPDATE
statement, as shown in the following example:
USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD +
(SELECT SUM(so.SubTotal)
FROM Sales.SalesOrderHeader AS so
WHERE so.OrderDate = (SELECT MAX(OrderDate)
FROM Sales.SalesOrderHeader AS so2
WHERE so2.SalesPersonID = so.SalesPersonID)
AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID
GROUP BY so.SalesPersonID);
GO
USE master;
GO
‐‐ Create a link to the remote data source.
‐‐ Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_
EXEC sp_addlinkedserver @server = N'MyLinkServer',
@srvproduct = N' ',
@provider = N'SQLNCLI10',
@datasrc = N'<server name>',
@catalog = N'AdventureWorks2012';
GO
USE AdventureWorks2012;
GO
‐‐ Specify the remote data source using a four‐part name
‐‐ in the form linked_server.catalog.schema.object.
UPDATE MyLinkServer.AdventureWorks2012.HumanResources.Department
SET GroupName = N'Public Relations'
WHERE DepartmentID = 4;
UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE
SET GroupName = 'Sales and Marketing';
UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE
SET GroupName = 'Sales and Marketing';
USE AdventureWorks2012;
GO
DECLARE @MyTableVar table (
SummaryBefore nvarchar(max),
SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT deleted.DocumentSummary,
inserted.DocumentSummary
INTO @MyTableVar
WHERE Title = N'Front Reflector Bracket Installation';
SELECT SummaryBefore, SummaryAfter
FROM @MyTableVar;
GO
B. Using UPDATE with .WRITE to add and remove data in an nvarchar(max) column
The following examples add and remove data from an nvarchar﴾max﴿ column that has a value
currently set to NULL. Because the .WRITE clause cannot be used to modify a NULL column, the
column is first populated with temporary data. This data is then replaced with the correct data
by using the .WRITE clause. The additional examples append data to the end of the column
value, remove ﴾truncate﴿ data from the column and, finally, remove partial data from the
column. The SELECT statements display the data modification generated by each UPDATE
statement.
USE AdventureWorks2012;
GO
‐‐ Replacing NULL value with temporary data.
UPDATE Production.Document
SET DocumentSummary = N'Replacing NULL value'
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
‐‐ Replacing temporary data with the correct data. Setting @Length to NULL
‐‐ truncates all existing data from the @Offset position.
UPDATE Production.Document
SET DocumentSummary .WRITE(N'Carefully inspect and maintain the tires and crank arms.'
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
‐‐ Appending additional data to the end of the column by setting
‐‐ @Offset to NULL.
UPDATE Production.Document
SET DocumentSummary .WRITE (N' Appending data to the end of the column.', NULL, 0)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
‐‐ Removing all data from @Offset to the end of the existing value by
‐‐ setting expression to NULL.
UPDATE Production.Document
SET DocumentSummary .WRITE (NULL, 56, 0)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
‐‐ Removing partial data beginning at position 9 and ending at
‐‐ position 21.
UPDATE Production.Document
SET DocumentSummary .WRITE ('',9, 12)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
USE AdventureWorks2012;
GO
UPDATE Production.ProductPhoto
SET ThumbNailPhoto = (
SELECT *
FROM OPENROWSET(BULK 'c:\Tires.jpg', SINGLE_BLOB) AS x )
WHERE ProductPhotoID = 1;
GO
UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' as varbinary(max))
WHERE [SerialNumber] = 2;
UPDATE dbo.Cities
SET Location = CONVERT(Point, '12.3:46.2')
WHERE Name = 'Anchorage';
B. Invoking a method
You can update a UDT by invoking a method, marked as a mutator, of the user‐defined type, to
perform the update. The following example invokes a mutator method of type Point named
SetXY. This updates the state of the instance of the type.
UPDATE dbo.Cities
SET Location.SetXY(23.5, 23.5)
WHERE Name = 'Anchorage';
UPDATE dbo.Cities
SET Location.X = 23.5
WHERE Name = 'Anchorage';
Caution
Because the SQL Server query optimizer typically selects the best execution plan for a query,
we recommend that hints be used only as a last resort by experienced developers and
database administrators.
USE AdventureWorks2012;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK‐%';
GO
USE AdventureWorks2012;
GO
CREATE PROCEDURE Production.uspProductUpdate
@Product nvarchar(25)
AS
SET NOCOUNT ON;
UPDATE Production.Product
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE @Product
OPTION (OPTIMIZE FOR (@Product = 'BK‐%') );
GO
‐‐ Execute the stored procedure
EXEC Production.uspProductUpdate 'BK‐%';
Two SELECT statements follow that return the values in @MyTableVar and the results of the
update operation in the Employee table. For more examples using the OUTPUT clause, see
OUTPUT Clause ﴾Transact‐SQL﴿.
USE AdventureWorks2012;
GO
DECLARE @MyTableVar table(
EmpID int NOT NULL,
OldVacationHours int,
NewVacationHours int,
ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25,
ModifiedDate = GETDATE()
OUTPUT inserted.BusinessEntityID,
deleted.VacationHours,
inserted.VacationHours,
inserted.ModifiedDate
INTO @MyTableVar;
‐‐Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
‐‐Display the result set of the table.
SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO
USE AdventureWorks2012;
GO
CREATE PROCEDURE HumanResources.Update_VacationHours
@NewHours smallint
AS
SET NOCOUNT ON;
UPDATE HumanResources.Employee
SET VacationHours =
( CASE
WHEN SalariedFlag = 0 THEN VacationHours + @NewHours
ELSE @NewHours
END
)
WHERE CurrentFlag = 1;
GO
EXEC HumanResources.Update_VacationHours 40;
USE AdventureWorks2012;
GO
BEGIN TRANSACTION;
BEGIN TRY
‐‐ Intentionally generate a constraint violation error.
UPDATE HumanResources.Department
SET Name = N'MyNewName'
WHERE DepartmentID BETWEEN 1 AND 2;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
See Also
Reference
CREATE TABLE ﴾Transact‐SQL﴿
CREATE TRIGGER ﴾Transact‐SQL﴿
Cursors ﴾Transact‐SQL﴿
DELETE ﴾Transact‐SQL﴿
INSERT ﴾Transact‐SQL﴿
Text and Image Functions ﴾Transact‐SQL﴿
WITH common_table_expression ﴾Transact‐SQL﴿
Concepts
FILESTREAM ﴾SQL Server﴿
© 2016 Microsoft
INSERT ﴾Transact‐SQL﴿
Adds one or more rows to a table or a view in SQL Server. For examples, see Examples.
Applies to: SQL Server ﴾SQL Server 2008 through current version﴿, Azure SQL Database.
Syntax
[ WITH <common_table_expression> [ ,...n ] ]
INSERT
{
[ TOP ( expression ) [ PERCENT ] ]
[ INTO ]
{ <object> | rowset_function_limited
[ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
}
{
[ ( column_list ) ]
[ <OUTPUT Clause> ]
{ VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n ]
| derived_table
| execute_statement
| <dml_table_source>
| DEFAULT VALUES
}
}
}
[;]
<object> ::=
{
[ server_name . database_name . schema_name .
| database_name .[ schema_name ] .
| schema_name .
]
table_or_view_name
}
<dml_table_source> ::=
SELECT <select_list>
FROM ( <dml_statement_with_output_clause> )
[AS] table_alias [ ( column_alias [ ,...n ] ) ]
[ WHERE <search_condition> ]
[ OPTION ( <query_hint> [ ,...n ] ) ]
‐‐ External tool only syntax
INSERT
{
[BULK]
[ database_name . [ schema_name ] . | schema_name . ]
[ table_name | view_name ]
( <column_definition> )
[ WITH (
[ [ , ] CHECK_CONSTRAINTS ]
[ [ , ] FIRE_TRIGGERS ]
[ [ , ] KEEP_NULLS ]
[ [ , ] KILOBYTES_PER_BATCH = kilobytes_per_batch ]
[ [ , ] ROWS_PER_BATCH = rows_per_batch ]
[ [ , ] ORDER ( { column [ ASC | DESC ] } [ ,...n ] ) ]
[ [ , ] TABLOCK ]
) ]
}
[; ] <column_definition> ::=
column_name <data_type>
[ COLLATE collation_name ]
[ NULL | NOT NULL ]
<data type> ::=
[ type_schema_name . ] type_name
[ ( precision [ , scale ] | max ]
Arguments
WITH <common_table_expression>
Specifies the temporary named result set, also known as common table expression,
defined within the scope of the INSERT statement. The result set is derived from a SELECT
statement. For more information, see WITH common_table_expression ﴾Transact‐SQL﴿.
INTO
Is an optional keyword that can be used between INSERT and the target table.
server_name
Is the name of the linked server on which the table or view is located. server_name can be
specified as a linked server name, or by using the OPENDATASOURCE function.
database_name
schema_name
Is the name of the schema to which the table or view belongs.
table_or view_name
Is the name of the table or view that is to receive the data.
A table variable, within its scope, can be used as a table source in an INSERT statement.
The view referenced by table_or_view_name must be updatable and reference exactly one
base table in the FROM clause of the view. For example, an INSERT into a multi‐table
view must use a column_list that references only columns from one base table. For more
information about updatable views, see CREATE VIEW ﴾Transact‐SQL﴿.
rowset_function_limited
READPAST, NOLOCK, and READUNCOMMITTED are not allowed. For more information
about table hints, see Table Hints ﴾Transact‐SQL﴿.
Important
Specifying the TABLOCK hint on a table that is the target of an INSERT statement has the
same effect as specifying the TABLOCKX hint. An exclusive lock is taken on the table.
﴾column_list﴿
Is a list of one or more columns in which to insert data. column_list must be enclosed in
parentheses and delimited by commas.
If a column is not in column_list, the Database Engine must be able to provide a value
based on the definition of the column; otherwise, the row cannot be loaded. The
Database Engine automatically provides a value for the column if the column:
column_list must be used when explicit values are inserted into an identity column, and
the SET IDENTITY_INSERT option must be ON for the table.
OUTPUT Clause
Returns inserted rows as part of the insert operation. The results can be returned to the
processing application or inserted into a table or table variable for further processing.
The OUTPUT clause is not supported in DML statements that reference local partitioned
views, distributed partitioned views, or remote tables, or INSERT statements that contain
an execute_statement. The OUTPUT INTO clause is not supported in INSERT statements
that contain a <dml_table_source> clause.
VALUES
Introduces the list or lists of data values to be inserted. There must be one data value for
each column in column_list, if specified, or in the table. The value list must be enclosed in
parentheses.
If the values in the Value list are not in the same order as the columns in the table or do
not have a value for each column in the table, column_list must be used to explicitly
specify the column that stores each incoming value.
You can use the Transact‐SQL row constructor ﴾also called a table value constructor﴿ to
specify multiple rows in a single INSERT statement. The row constructor consists of a
single VALUES clause with multiple value lists enclosed in parentheses and separated by
a comma. For more information, see Table Value Constructor ﴾Transact‐SQL﴿.
DEFAULT
Forces the Database Engine to load the default value defined for a column. If a default
does not exist for the column and the column allows null values, NULL is inserted. For a
column defined with the timestamp data type, the next timestamp value is inserted.
DEFAULT is not valid for an identity column.
expression
Is a constant, a variable, or an expression. The expression cannot contain an EXECUTE
statement.
When referencing the Unicode character data types nchar, nvarchar, and ntext,
'expression' should be prefixed with the capital letter 'N'. If 'N' is not specified, SQL Server
converts the string to the code page that corresponds to the default collation of the
database or column. Any characters not found in this code page are lost.
derived_table
Is any valid SELECT statement that returns rows of data to be loaded into the table. The
SELECT statement cannot contain a common table expression ﴾CTE﴿.
execute_statement
Is any valid EXECUTE statement that returns data with SELECT or READTEXT statements.
For more information, see EXECUTE ﴾Transact‐SQL﴿.
The RESULT SETS options of the EXECUTE statement cannot be specified in an INSERT…
EXEC statement.
If execute_statement is used with INSERT, each result set must be compatible with the
columns in the table or in column_list.
<dml_table_source>
Specifies that the rows inserted into the target table are those returned by the OUTPUT
clause of an INSERT, UPDATE, DELETE, or MERGE statement, optionally filtered by a
WHERE clause. If <dml_table_source> is specified, the target of the outer INSERT
statement must meet the following restrictions:
The compatibility level of the database must be set to 100 or higher. For more
information, see OUTPUT Clause ﴾Transact‐SQL﴿.
<select_list>
Is a comma‐separated list specifying which columns returned by the OUTPUT clause to
insert. The columns in <select_list> must be compatible with the columns into which
values are being inserted. <select_list> cannot reference aggregate functions or
TEXTPTR.
Note
Any variables listed in the SELECT list refer to their original values, regardless of any
changes made to them in <dml_statement_with_output_clause>.
<dml_statement_with_output_clause>
Is a valid INSERT, UPDATE, DELETE, or MERGE statement that returns affected rows in an
OUTPUT clause. The statement cannot contain a WITH clause, and cannot target remote
tables or partitioned views. If UPDATE or DELETE is specified, it cannot be a cursor‐based
UPDATE or DELETE. Source rows cannot be referenced as nested DML statements.
WHERE <search_condition>
Is any WHERE clause containing a valid <search_condition> that filters the rows returned
by <dml_statement_with_output_clause>. For more information, see Search Condition
﴾Transact‐SQL﴿. When used in this context, <search_condition> cannot contain
subqueries, scalar user‐defined functions that perform data access, aggregate functions,
TEXTPTR, or full‐text search predicates.
DEFAULT VALUES
Forces the new row to contain the default values defined for each column.
BULK
Used by external tools to upload a binary data stream. This option is not intended for use
with tools such as SQL Server Management Studio, SQLCMD, OSQL, or data access
application programming interfaces such as SQL Server Native Client.
FIRE_TRIGGERS
Specifies that any insert triggers defined on the destination table execute during the
binary data stream upload operation. For more information, see BULK INSERT ﴾Transact‐
SQL﴿.
CHECK_CONSTRAINTS
Specifies that all constraints on the target table or view must be checked during the
binary data stream upload operation. For more information, see BULK INSERT ﴾Transact‐
SQL﴿.
KEEPNULLS
Specifies that empty columns should retain a null value during the binary data stream
upload operation. For more information, see Keep Nulls or Use Default Values During
Bulk Import ﴾SQL Server﴿.
KILOBYTES_PER_BATCH = kilobytes_per_batch
Specifies the approximate number of kilobytes ﴾KB﴿ of data per batch as
kilobytes_per_batch. For more information, see BULK INSERT ﴾Transact‐SQL﴿.
ROWS_PER_BATCH =rows_per_batch
Indicates the approximate number of rows of data in the binary data stream. For more
information, see BULK INSERT ﴾Transact‐SQL﴿.
Rows that are inserted into a heap as the result of an insert action in a MERGE statement may
also be minimally logged.
Unlike the BULK INSERT statement, which holds a less restrictive Bulk Update lock, INSERT
INTO…SELECT with the TABLOCK hint holds an exclusive ﴾X﴿ lock on the table. This means that
you cannot insert rows using parallel insert operations.
The TABLOCK hint can minimize the number of log records for the insert operation. The
recovery model of the database must be set to simple or bulk‐logged and the target
table cannot be used in replication. For more information, see Prerequisites for Minimal
Logging in Bulk Import.
The IGNORE_CONSTRAINTS hint can temporarily disable FOREIGN KEY and CHECK
constraint checking.
The KEEPDEFAULTS hint allows the insertion of a table column's default value, if any,
instead of NULL when the data record lacks a value for the column.
The KEEPIDENTITY hint allows the identity values in the imported data file to be used for
the identity column in the target table.
These optimizations are similar to those available with the BULK INSERT command. For more
information, see Table Hints ﴾Transact‐SQL﴿.
Data Types
When you insert rows, consider the following data type behavior:
If a value is being loaded into columns with a char, varchar, or varbinary data type, the
padding or truncation of trailing blanks ﴾spaces for char and varchar, zeros for
varbinary﴿ is determined by the SET ANSI_PADDING setting defined for the column
when the table was created. For more information, see SET ANSI_PADDING ﴾Transact‐
SQL﴿.
The following table shows the default operation for SET ANSI_PADDING OFF.
Data
Default operation
type
If an empty string ﴾' '﴿ is loaded into a column with a varchar or text data type, the
default operation is to load a zero‐length string.
Inserting a null value into a text or image column does not create a valid text pointer,
nor does it preallocate an 8‐KB text page.
Columns created with the uniqueidentifier data type store specially formatted 16‐byte
binary values. Unlike with identity columns, the Database Engine does not automatically
generate values for columns with the uniqueidentifier data type. During an insert
operation, variables with a data type of uniqueidentifier and string constants in the
form xxxxxxxx‐xxxx‐xxxx‐xxxx‐xxxxxxxxxxxx ﴾36 characters including hyphens, where x is a
hexadecimal digit in the range 0‐9 or a‐f﴿ can be used for uniqueidentifier columns. For
example, 6F9619FF‐8B86‐D011‐B42D‐00C04FC964FF is a valid value for a
uniqueidentifier variable or column. Use the NEWID﴾﴿ function to obtain a globally
unique ID ﴾GUID﴿.
Supplying a value in a SQL Server system data type, as long as the user‐defined type
supports implicit or explicit conversion from that type. The following example shows how
to insert a value in a column of user‐defined type Point, by explicitly converting from a
string.
INSERT INTO Cities (Location)
VALUES ( CONVERT(Point, '12.3:46.2') );
A binary value can also be supplied without performing explicit conversion, because all
user‐defined types are implicitly convertible from binary.
Calling a user‐defined function that returns a value of the user‐defined type. The
following example uses a user‐defined function CreateNewPoint() to create a new
value of user‐defined type Point and insert the value into the Cities table.
INSERT INTO Cities (Location)
VALUES ( dbo.CreateNewPoint(x, y) );
Error Handling
You can implement error handling for the INSERT statement by specifying the statement in a
TRY…CATCH construct.
If an INSERT statement violates a constraint or rule, or if it has a value incompatible with the
data type of the column, the statement fails and an error message is returned.
If INSERT is loading multiple rows with SELECT or EXECUTE, any violation of a rule or constraint
that occurs from the values being loaded causes the statement to be stopped, and no rows are
loaded.
Interoperability
When an INSTEAD OF trigger is defined on INSERT actions against a table or view, the trigger
executes instead of the INSERT statement. For more information about INSTEAD OF triggers, see
CREATE TRIGGER ﴾Transact‐SQL﴿.
When TOP is used with INSERT the referenced rows are not arranged in any order and the
ORDER BY clause can not be directly specified in this statements. If you need to use TOP to
insert rows in a meaningful chronological order, you must use TOP together with an ORDER BY
clause that is specified in a subselect statement. See the Examples section that follows in this
topic.
Logging Behavior
The INSERT statement is always fully logged except when using the OPENROWSET function with
the BULK keyword or when using INSERT INTO <target_table> SELECT <columns> FROM
<source_table>. These operations can be minimally logged. For more information, see the
section "Best Practices for Bulk Loading Data" earlier in this topic.
Security
During a linked server connection, the sending server provides a login name and password to
connect to the receiving server on its behalf. For this connection to work, you must create a
login mapping between the linked servers by using sp_addlinkedsrvlogin.
When you use OPENROWSET﴾BULK…﴿, it is important to understand how SQL Server handles
impersonation. For more information, see "Security Considerations" in Import Bulk Data by
Using BULK INSERT or OPENROWSET﴾BULK...﴿ ﴾SQL Server﴿.
Permissions
INSERT permission is required on the target table.
INSERT permissions default to members of the sysadmin fixed server role, the db_owner and
db_datawriter fixed database roles, and the table owner. Members of the sysadmin, db_owner,
and the db_securityadmin roles, and the table owner can transfer permissions to other users.
To execute INSERT with the OPENROWSET function BULK option, you must be a member of the
sysadmin fixed server role or of the bulkadmin fixed server role.
Examples
Inserting rows into a remote table Linked server • OPENQUERY rowset function •
OPENDATASOURCE rowset function
Basic Syntax
Examples in this section demonstrate the basic functionality of the INSERT statement using the
minimum required syntax.
INSERT INTO Production.UnitMeasure
VALUES (N'FT', N'Feet', '20080414');
INSERT INTO Production.UnitMeasure
VALUES (N'FT2', N'Square Feet ', '20080923'), (N'Y', N'Yards', '20080923'), (N'Y3', N'
C. Inserting data that is not in the same order as the table columns
The following example uses a column list to explicitly specify the values that are inserted into
each column. The column order in the Production.UnitMeasure table in the
AdventureWorks2012 database is UnitMeasureCode, Name, ModifiedDate; however, the
columns are not listed in that order in column_list.
INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode,
ModifiedDate)
VALUES (N'Square Yards', N'Y2', GETDATE());
A. Inserting data into a table with columns that have default values
The following example shows inserting rows into a table with columns that automatically
generate a value or have a default value. Column_1 is a computed column that automatically
generates a value by concatenating a string with the value inserted into column_2. Column_2 is
defined with a default constraint. If a value is not specified for this column, the default value is
used. Column_3 is defined with the rowversion data type, which automatically generates a
unique, incrementing binary number. Column_4 does not automatically generate a value. When
a value for this column is not specified, NULL is inserted. The INSERT statements insert rows that
contain values for some of the columns but not all. In the last INSERT statement, no columns are
specified and only the default values are inserted by using the DEFAULT VALUES clause.
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1
(
column_1 AS 'Computed column ' + column_2,
column_2 varchar(30)
CONSTRAINT default_name DEFAULT ('my column default'),
column_3 rowversion,
column_4 varchar(40) NULL
);
GO
INSERT INTO dbo.T1 (column_4)
VALUES ('Explicit value');
INSERT INTO dbo.T1 (column_2, column_4)
VALUES ('Explicit value', 'Explicit value');
INSERT INTO dbo.T1 (column_2)
VALUES ('Explicit value');
INSERT INTO T1 DEFAULT VALUES;
GO
SELECT column_1, column_2, column_3, column_4
FROM dbo.T1;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1
(
column_1 int IDENTITY,
column_2 uniqueidentifier,
);
GO
INSERT INTO dbo.T1 (column_2)
VALUES (NEWID());
INSERT INTO T1 DEFAULT VALUES;
GO
SELECT column_1, column_2
FROM dbo.T1;
INSERT INTO dbo.Points (PointValue) VALUES (CONVERT(Point, '3,4'));
INSERT INTO dbo.Points (PointValue) VALUES (CONVERT(Point, '1,5'));
INSERT INTO dbo.Points (PointValue) VALUES (CAST ('1,99' AS Point));
Inserting Data from Other Tables
Examples in this section demonstrate methods of inserting rows from one table into another
table.
A. Using the SELECT and EXECUTE options to insert data from other tables
The following example shows how to insert data from one table into another table by using
INSERT…SELECT or INSERT…EXECUTE. Each is based on a multi‐table SELECT statement that
includes an expression and a literal value in the column list.
The first INSERT statement uses a SELECT statement to derive the data from the source tables
﴾Employee, SalesPerson, and Person﴿ in the AdventureWorks2012 database and store the
result set in the EmployeeSales table. The second INSERT statement uses the EXECUTE clause
to call a stored procedure that contains the SELECT statement, and the third INSERT uses the
EXECUTE clause to reference the SELECT statement as a literal string.
IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeSales;
GO
IF OBJECT_ID ('dbo.uspGetEmployeeSales', 'P') IS NOT NULL
DROP PROCEDURE uspGetEmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
( DataSource varchar(20) NOT NULL,
BusinessEntityID varchar(11) NOT NULL,
LastName varchar(40) NOT NULL,
SalesDollars money NOT NULL
);
GO
CREATE PROCEDURE dbo.uspGetEmployeeSales
AS
SET NOCOUNT ON;
SELECT 'PROCEDURE', sp.BusinessEntityID, c.LastName,
sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.BusinessEntityID LIKE '2%'
ORDER BY sp.BusinessEntityID, c.LastName;
GO
‐‐INSERT...SELECT example
INSERT INTO dbo.EmployeeSales
SELECT 'SELECT', sp.BusinessEntityID, c.LastName, sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.BusinessEntityID LIKE '2%'
ORDER BY sp.BusinessEntityID, c.LastName;
GO
‐‐INSERT...EXECUTE procedure example
INSERT INTO dbo.EmployeeSales
EXECUTE dbo.uspGetEmployeeSales;
GO
‐‐INSERT...EXECUTE('string') example
INSERT INTO dbo.EmployeeSales
EXECUTE
('
SELECT ''EXEC STRING'', sp.BusinessEntityID, c.LastName,
sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.BusinessEntityID LIKE ''2%''
ORDER BY sp.BusinessEntityID, c.LastName
');
GO
‐‐Show results.
SELECT DataSource,BusinessEntityID,LastName,SalesDollars
FROM dbo.EmployeeSales;
IF OBJECT_ID (N'HumanResources.NewEmployee', N'U') IS NOT NULL
DROP TABLE HumanResources.NewEmployee;
GO
CREATE TABLE HumanResources.NewEmployee
(
EmployeeID int NOT NULL,
LastName nvarchar(50) NOT NULL,
FirstName nvarchar(50) NOT NULL,
PhoneNumber Phone NULL,
AddressLine1 nvarchar(60) NOT NULL,
City nvarchar(30) NOT NULL,
State nchar(3) NOT NULL,
PostalCode nvarchar(15) NOT NULL,
CurrentFlag Flag
);
GO
WITH EmployeeTemp (EmpID, LastName, FirstName, Phone,
Address, City, StateProvince,
PostalCode, CurrentFlag)
AS (SELECT
e.BusinessEntityID, c.LastName, c.FirstName, pp.PhoneNumber,
a.AddressLine1, a.City, sp.StateProvinceCode,
a.PostalCode, e.CurrentFlag
FROM HumanResources.Employee e
INNER JOIN Person.BusinessEntityAddress AS bea
ON e.BusinessEntityID = bea.BusinessEntityID
INNER JOIN Person.Address AS a
ON bea.AddressID = a.AddressID
INNER JOIN Person.PersonPhone AS pp
ON e.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Person.StateProvince AS sp
ON a.StateProvinceID = sp.StateProvinceID
INNER JOIN Person.Person as c
ON e.BusinessEntityID = c.BusinessEntityID
)
INSERT INTO HumanResources.NewEmployee
SELECT EmpID, LastName, FirstName, Phone,
Address, City, StateProvince, PostalCode, CurrentFlag
FROM EmployeeTemp;
GO
C. Using TOP to limit the data inserted from the source table
The following example creates the table EmployeeSales and inserts the name and year‐to‐date
sales data for the top 5 random employees from the table HumanResources.Employee in the
AdventureWorks2012 database. The INSERT statement chooses any 5 rows returned by the
SELECT statement. The OUTPUT clause displays the rows that are inserted into the
EmployeeSales table. Notice that the ORDER BY clause in the SELECT statement is not used to
determine the top 5 employees.
IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
( EmployeeID nvarchar(11) NOT NULL,
LastName nvarchar(20) NOT NULL,
FirstName nvarchar(20) NOT NULL,
YearlySales money NOT NULL
);
GO
INSERT TOP(5)INTO dbo.EmployeeSales
OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.Yearly
SELECT sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.SalesYTD > 250000.00
ORDER BY sp.SalesYTD DESC;
If you have to use TOP to insert rows in a meaningful chronological order, you must use TOP
together with ORDER BY in a subselect statement as shown in the following example. The
OUTPUT clause displays the rows that are inserted into the EmployeeSales table. Notice that
the top 5 employees are now inserted based on the results of the ORDER BY clause instead of
random rows.
INSERT INTO dbo.EmployeeSales
OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.Yearly
SELECT TOP (5) sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.SalesYTD > 250000.00
ORDER BY sp.SalesYTD DESC;
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
DROP TABLE dbo.T1;
GO
IF OBJECT_ID ('dbo.V1', 'V') IS NOT NULL
DROP VIEW dbo.V1;
GO
CREATE TABLE T1 ( column_1 int, column_2 varchar(30));
GO
CREATE VIEW V1 AS
SELECT column_2, column_1
FROM T1;
GO
INSERT INTO V1
VALUES ('Row 1',1);
GO
SELECT column_1, column_2
FROM T1;
GO
SELECT column_1, column_2
FROM V1;
GO
‐‐ Create the table variable.
DECLARE @MyTableVar table(
LocationID int NOT NULL,
CostRate smallmoney NOT NULL,
NewCostRate AS CostRate * 1.5,
ModifiedDate datetime);
‐‐ Insert values into the table variable.
INSERT INTO @MyTableVar (LocationID, CostRate, ModifiedDate)
SELECT LocationID, CostRate, GETDATE() FROM Production.Location
WHERE CostRate > 0;
‐‐ View the table variable result set.
SELECT * FROM @MyTableVar;
GO
USE master;
GO
‐‐ Create a link to the remote data source.
‐‐ Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_
EXEC sp_addlinkedserver @server = N'MyLinkServer',
@srvproduct = N' ',
@provider = N'SQLNCLI',
@datasrc = N'server_name',
@catalog = N'AdventureWorks2012';
GO
‐‐ Specify the remote data source in the FROM clause using a four‐part name
‐‐ in the form linked_server.catalog.schema.object.
INSERT INTO MyLinkServer.AdventureWorks2012.HumanResources.Department (Name, GroupName
VALUES (N'Public Relations', N'Executive General and Administration');
GO
‐‐ Use the OPENDATASOURCE function to specify the remote data source.
‐‐ Specify a valid server name for Data Source using the format server_name or server_
INSERT INTO OPENDATASOURCE('SQLNCLI',
'Data Source= <server_name>; Integrated Security=SSPI')
.AdventureWorks2012.HumanResources.Department (Name, GroupName)
VALUES (N'Standards and Methods', 'Quality Assurance');
GO
‐‐ Create the target heap.
CREATE TABLE Sales.SalesHistory(
SalesOrderID int NOT NULL,
SalesOrderDetailID int NOT NULL,
CarrierTrackingNumber nvarchar(25) NULL,
OrderQty smallint NOT NULL,
ProductID int NOT NULL,
SpecialOfferID int NOT NULL,
UnitPrice money NOT NULL,
UnitPriceDiscount money NOT NULL,
LineTotal money NOT NULL,
rowguid uniqueidentifier ROWGUIDCOL NOT NULL,
ModifiedDate datetime NOT NULL );
GO
‐‐ Temporarily set the recovery model to BULK_LOGGED.
ALTER DATABASE AdventureWorks2012
SET RECOVERY BULK_LOGGED;
GO
‐‐ Transfer data from Sales.SalesOrderDetail to Sales.SalesHistory
INSERT INTO Sales.SalesHistory WITH (TABLOCK)
(SalesOrderID,
SalesOrderDetailID,
CarrierTrackingNumber,
OrderQty,
ProductID,
SpecialOfferID,
UnitPrice,
UnitPriceDiscount,
LineTotal,
rowguid,
ModifiedDate)
SELECT * FROM Sales.SalesOrderDetail;
GO
‐‐ Reset the recovery model.
ALTER DATABASE AdventureWorks2012
SET RECOVERY FULL;
GO
B. Using the OPENROWSET function with BULK to bulk load data into a table
The following example inserts rows from a data file into a table by specifying the OPENROWSET
function. The IGNORE_TRIGGERS table hint is specified for performance optimization. For more
examples, see Import Bulk Data by Using BULK INSERT or OPENROWSET﴾BULK...﴿ ﴾SQL Server﴿.
‐‐ Use the OPENROWSET function to specify the data source and specifies the IGNORE_TRI
INSERT INTO HumanResources.Department WITH (IGNORE_TRIGGERS) (Name, GroupName)
SELECT b.Name, b.GroupName
FROM OPENROWSET (
BULK 'C:\SQLFiles\DepartmentData.txt',
FORMATFILE = 'C:\SQLFiles\BulkloadFormatFile.xml',
ROWS_PER_BATCH = 15000)AS b ;
Caution
Because the SQL Server query optimizer typically selects the best execution plan for a query,
we recommend that hints be used only as a last resort by experienced developers and
database administrators.
INSERT INTO Production.Location WITH (XLOCK)
(Name, CostRate, Availability)
VALUES ( N'Final Inventory', 15.00, 80.00);
DECLARE @MyTableVar table( NewScrapReasonID smallint,
Name varchar(50),
ModifiedDate datetime);
INSERT Production.ScrapReason
OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
INTO @MyTableVar
VALUES (N'Operator error', GETDATE());
‐‐Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
‐‐Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate
FROM Production.ScrapReason;
INSERT INTO dbo.EmployeeSales (LastName, FirstName, CurrentSales)
OUTPUT INSERTED.LastName,
INSERTED.FirstName,
INSERTED.CurrentSales
INTO @MyTableVar
SELECT c.LastName, c.FirstName, sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.BusinessEntityID LIKE '2%'
ORDER BY c.LastName, c.FirstName;
SELECT LastName, FirstName, CurrentSales
FROM @MyTableVar;
GO
SELECT EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales
FROM dbo.EmployeeSales;
IF OBJECT_ID(N'Production.ZeroInventory', N'U') IS NOT NULL
DROP TABLE Production.ZeroInventory;
GO
‐‐Create ZeroInventory table.
CREATE TABLE Production.ZeroInventory (DeletedProductID int, RemovedOnDate DateTime);
GO
INSERT INTO Production.ZeroInventory (DeletedProductID, RemovedOnDate)
SELECT ProductID, GETDATE()
FROM
( MERGE Production.ProductInventory AS pi
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod
JOIN Sales.SalesOrderHeader AS soh
ON sod.SalesOrderID = soh.SalesOrderID
AND soh.OrderDate = '20070401'
GROUP BY ProductID) AS src (ProductID, OrderQty)
ON (pi.ProductID = src.ProductID)
WHEN MATCHED AND pi.Quantity ‐ src.OrderQty <= 0
THEN DELETE
WHEN MATCHED
THEN UPDATE SET pi.Quantity = pi.Quantity ‐ src.OrderQty
OUTPUT $action, deleted.ProductID) AS Changes (Action, ProductID)
WHERE Action = 'DELETE';
IF @@ROWCOUNT = 0
PRINT 'Warning: No rows were inserted';
GO
SELECT DeletedProductID, RemovedOnDate FROM Production.ZeroInventory;
See Also
Reference
BULK INSERT ﴾Transact‐SQL﴿
DELETE ﴾Transact‐SQL﴿
EXECUTE ﴾Transact‐SQL﴿
FROM ﴾Transact‐SQL﴿
IDENTITY ﴾Property﴿ ﴾Transact‐SQL﴿
NEWID ﴾Transact‐SQL﴿
SELECT ﴾Transact‐SQL﴿
UPDATE ﴾Transact‐SQL﴿
MERGE ﴾Transact‐SQL﴿
OUTPUT Clause ﴾Transact‐SQL﴿
Concepts
Use the inserted and deleted Tables
© 2016 Microsoft
Get Information
About a View
Get Information About a View
SQL Server 2014
You can gain information about a view’s definition or properties in SQL Server 2014 by using SQL
Server Management Studio or Transact‐SQL. You may need to see the definition of the view to
understand how its data is derived from the source tables or to see the data defined by the view.
Important
If you change the name of an object referenced by a view, you must modify the view so that its
text reflects the new name. Therefore, before renaming an object, display the dependencies of
the object first to determine if any views are affected by the proposed change.
In This Topic
Security
Using Transact‐SQL
Security
Permissions
Using sp_helptext to return the definition of a view requires membership in the public
role. Using sys.sql_expression_dependencies to find all the dependencies on a view
requires VIEW DEFINITION permission on the database and SELECT permission on
sys.sql_expression_dependencies for the database. System object definitions, like the
ones returned in SELECT OBJECT_DEFINITION, are publicly visible.
1. In Object Explorer, click the plus sign next to the database that contains the view to
which you want to view the properties, and then click the plus sign to expand the Views
folder.
2. Right‐click the view of which you want to view the properties and select Properties.
Database
The name of the database containing this view.
Server
The name of the current server instance.
User
The name of the user of this connection.
Created date
Displays the date the view was created.
Name
The name of the current view.
Schema
Displays the schema that owns the view.
System object
Indicates whether the view is a system object. Values are True and False.
ANSI NULLs
Indicates if the object was created with the ANSI NULLs option.
Encrypted
Indicates whether the view is encrypted. Values are True and False.
Quoted identifier
Indicates if the object was created with the quoted identifier option.
Schema bound
Indicates whether the view is schema‐bound. Values are True and False. For
information about schema‐bound views, see the SCHEMABINDING portion of
CREATE VIEW ﴾Transact‐SQL﴿.
1. In Object Explorer, expand the database that contains the view to which you want to
view the properties, and then expand the Views folder.
2. Right‐click the view of which you want to view the properties and select Design.
3. Right‐click in the blank space of the Diagram pane and click Properties.
Database Name
The name of the database containing this view.
Description
A brief description of the current view.
Schema
Displays the schema that owns the view.
Server Name
The name of the current server instance.
Bind to Schema
Prevents users from modifying the underlying objects that contribute to this view
in any way that would invalidate the view definition.
Deterministic
Shows whether the data type of the selected column can be determined with
certainty
Distinct Values
Specifies that the query will filter out duplicates in the view. This option is useful
when you are using only some of the columns from a table and those columns
might contain duplicate values, or when the process of joining two or more tables
produces duplicate rows in the result set. Choosing this option is equivalent to
inserting the keyword DISTINCT into the statement in the SQL pane.
GROUP BY Extension
Specifies that additional options for views based on aggregate queries are
available.
SQL Comment
Shows a description of the SQL statements. To see the entire description, or to
edit it, click the description and then click the ellipses ﴾…﴿ to the right of the
property. Your comments might include information such as who uses the view
and when they use it.
Top Specification
Expands to show properties for the Top, Expression, Percent, and With Ties
properties.
﴾Top﴿
Specifies that the view will include a TOP clause, which returns only the first n
rows or first n percentage of rows in the result set. The default is that the view
returns the first 10 rows in the result set. Use this to change the number of rows
to return or to specify a different percentage
Expression
Shows what percent ﴾if Percent is set to Yes﴿ or records ﴾if Percent is set to No﴿
that the view will return.
Percent
Specifies that the query will include a TOP clause, returning only the first n
percentage of rows in the result set
With Ties
Specifies that the view will include a WITH TIES clause. WITH TIES is useful if a
view includes an ORDER BY clause and a TOP clause based on percentage. If this
option is set, and if the percentage cutoff falls in the middle of a set of rows with
identical values in the ORDER BY clause, the view is extended to include all such
rows.
Update Specification
Expands to show properties for the Update Using View Rules and Check Option
properties.
In some cases, MDAC manifests view update and view insert operations as
updates and inserts against the view's underlying base tables. By selecting Update
Using View Rules, you can ensure that MDAC generates update and insert
operations against the view itself.
Check Option
Indicates that when you open this view and modify the Results pane, the data
source checks whether the added or modified data satisfies the WHERE clause of
the view definition. If your modification do not satisfy the WHERE clause, you will
see an error with more information.
1. In Object Explorer, expand the database that contains the view to which you want to
view the properties, and then expand the Views folder.
2. Right‐click the view of which you want to view the properties and select View
Dependencies.
3. Select Objects that depend on [view name] to display the objects that refer to the view.
4. Select Objects on which [view name] depends to display the objects that are
referenced by the view.
Using Transact-SQL
3. Copy and paste one of the following examples into the query window and click Execute.
USE AdventureWorks2012;
GO
SELECT definition, uses_ansi_nulls, uses_quoted_identifier, is_schema_bound
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('HumanResources.vEmployee');
GO
USE AdventureWorks2012;
GO
SELECT OBJECT_DEFINITION (OBJECT_ID('HumanResources.vEmployee')) AS ObjectDefinit
GO
EXEC sp_helptext 'HumanResources.vEmployee';
3. Copy and paste the following example into the query window and click Execute.
USE AdventureWorks2012;
GO
SELECT OBJECT_NAME(referencing_id) AS referencing_entity_name,
o.type_desc AS referencing_desciption,
COALESCE(COL_NAME(referencing_id, referencing_minor_id), '(n/a)') AS referenc
referencing_class_desc, referenced_class_desc,
referenced_server_name, referenced_database_name, referenced_schema_name,
referenced_entity_name,
COALESCE(COL_NAME(referenced_id, referenced_minor_id), '(n/a)') AS referenced
is_caller_dependent, is_ambiguous
FROM sys.sql_expression_dependencies AS sed
INNER JOIN sys.objects AS o ON sed.referencing_id = o.object_id
WHERE referencing_id = OBJECT_ID(N'Production.vProductAndDescription');
GO
© 2016 Microsoft
Rename Views
Rename Views
SQL Server 2014
You can rename a view in SQL Server 2014 by using SQL Server Management Studio or Transact‐
SQL.
Warning
If you rename a view, code and applications that depend on the view may fail. These include
other views, queries, stored procedures, user‐defined functions, and client applications. Note
that these failures will cascade.
In This Topic
Prerequisites
Security
Using Transact‐SQL
Prerequisites
Obtain a list of all dependencies on the view. Any objects, scripts or applications that
reference the view must be modified to reflect the new name of the view. For more
information, see Get Information About a View. We recommend that you drop the view and
recreate it with a new name instead of renaming the view. By recreating the view, you update
the dependency information for the objects that are referenced in the view.
Security
Permissions
Requires ALTER permission on SCHEMA or CONTROL permission on OBJECT is required,
and CREATE VIEW permission in the database.
To rename a view
1. In Object Explorer, expand the database that contains the view you wish to rename and
then expand the View folder.
Using Transact-SQL
To rename a view
While you can use sp_rename to change the name of the view, we recommend that you delete
the existing view and then re‐create it with the new name.
For more information, see CREATE VIEW ﴾Transact‐SQL﴿ and DROP VIEW ﴾Transact‐SQL﴿.
Follow Up: After Renaming a View
Ensure that all objects, scripts, and applications that reference the view’s old name now use the
new name.
© 2016 Microsoft
Delete Views
Delete Views
SQL Server 2014
You can delete ﴾drop﴿ views in SQL Server 2014 by using SQL Server Management Studio or
Transact‐SQL
In This Topic
Security
Using Transact‐SQL
Any view on a table that is dropped by using DROP TABLE must be dropped explicitly
by using DROP VIEW.
Security
Permissions
Requires ALTER permission on SCHEMA or CONTROL permission on OBJECT.
1. In Object Explorer, expand the database that contains the view you want to delete, and
then expand the Views folder.
Important
Click Show Dependencies in the Delete Object dialog box to open the
view_nameDependencies dialog box. This will show all of the objects that depend on
the view and all of the objects on which the view depends.
Using Transact-SQL
3. Copy and paste the following example into the query window and click Execute. The
example deletes the specified view only if the view already exists.
USE AdventureWorks2012 ;
GO
IF OBJECT_ID ('HumanResources.EmployeeHireDate', 'V') IS NOT NULL
DROP VIEW HumanResources.EmployeeHireDate;
GO
© 2016 Microsoft
Removes one or more views from the current database. DROP VIEW can be executed against
indexed views.
Applies to: SQL Server ﴾SQL Server 2008 through current version﴿, Azure SQL Database.
Syntax
DROP VIEW [ schema_name . ] view_name [ ...,n ] [ ; ]
Arguments
schema_name
Is the name of the schema to which the view belongs.
view_name
Is the name of the view to remove.
Remarks
When you drop a view, the definition of the view and other information about the view is
deleted from the system catalog. All permissions for the view are also deleted.
Any view on a table that is dropped by using DROP TABLE must be dropped explicitly by using
DROP VIEW.
When executed against an indexed view, DROP VIEW automatically drops all indexes on a view.
To display all indexes on a view, use sp_helpindex.
When querying through a view, the Database Engine checks to make sure that all the database
objects referenced in the statement exist and that they are valid in the context of the statement,
and that data modification statements do not violate any data integrity rules. A check that fails
returns an error message. A successful check translates the action into an action against the
underlying table or tables. If the underlying tables or views have changed since the view was
originally created, it may be useful to drop and re‐create the view.
For more information about determining dependencies for a specific view, see
sys.sql_dependencies ﴾Transact‐SQL﴿.
For more information about viewing the text of the view, see sp_helptext ﴾Transact‐SQL﴿.
Permissions
Requires CONTROL permission on the view, ALTER permission on the schema containing the
view, or membership in the db_ddladmin fixed server role.
Examples
The following example removes the view Reorder.
Transact‐SQL
USE AdventureWorks2012 ;
GO
IF OBJECT_ID ('dbo.Reorder', 'V') IS NOT NULL
DROP VIEW dbo.Reorder ;
GO
See Also
Reference
ALTER VIEW ﴾Transact‐SQL﴿
CREATE VIEW ﴾Transact‐SQL﴿
EVENTDATA ﴾Transact‐SQL﴿
sys.columns ﴾Transact‐SQL﴿
sys.objects ﴾Transact‐SQL﴿
USE ﴾Transact‐SQL﴿
sys.sql_expression_dependencies ﴾Transact‐SQL﴿
© 2016 Microsoft