Friday, March 26, 2010
Clearing the cache of a LINQ to SQL DataContext
Internal methods are, however, available through reflection (I'm a bit of a noob when it comes to reflection so there might be constraints on when they are and when they aren't but this works for me). In order to make it easy to clear the cache (for example, after saving but before retrieving the object from the database for checking it saved correctly) I have created an extension method to do the heavy lifting for me:
using System.Data.Linq;
using System.Reflection;
namespace MyNamespace
{
public static class Extensions
{
public static void ClearCache(this DataContext context)
{
const BindingFlags FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
var method = context.GetType().GetMethod("ClearCache", FLAGS);
method.Invoke(context, null);
}
}
}
//Usage example: (will NOT compile unless you change the Abc below and include it's namespace...)
public class Xyz
{
public void DoWork()
{//'Abc being whatever your particular SQL Metal-generated data context is called
AbcDataContext dataContext = new AbcDataContext("my optional connection string");
//do work...
//check out the 'Extension Method' magic! Now the our custom static method defined above can be called like this:
dataContext.ClearCache();
//do more work...
//take a break...
}
}
Saturday, March 20, 2010
Cannot add diagram to SQL Server 2005 DB: Database diagram support objects cannot be installed because this database does not have a valid owner.
EXEC sp_dbcmptlevel 'dbname', '90';
ALTER AUTHORIZATION ON DATABASE::dbname TO valid_login
Friday, March 19, 2010
Creating an Index
- Syntax:
- CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ]
INDEX index_name ON table ( column1, ... )
[ WITH
[ PAD_INDEX ]
[ [ , ] FILLFACTOR = fillfactor1 ]
[ [ , ] IGNORE_DUP_KEY ]
[ [ , ] DROP_EXISTING ]
[ [ , ] STATISTICS_NORECOMPUTE ]
]
[ ON filegroup1 ] - UNIQUE
- Indicates that a unique index is to be created.
- CLUSTERED
- Indicates that the index created is a clustered index.
- NONCLUSTERED
- Indicates that the index created is a nonclustered index.
- index_name
- Is the name of the index.
- table
- The name of the table on which the index is to be created.
- column1, ...
- The column or columns to which the index is to be applied.
- PAD_INDEX
- Specifies the space to be left open on each page (node) in the intermediate levels of the index. (This is useful only when FILLFACTOR is specified).
- FILLFACTOR = fillfactor1
- Specifies the fillfactor for the index as fillfactor1.
- IGNORE_DUP_KEY
- Controls what happens when an attempt is made to insert a duplicate key value into a column that is part of a unique clustered index.
- DROP_EXISTING
- Specifies that the named, preexisting clustered or nonclustered index should be dropped and the specified index rebuilt.
- STATISTICS_NORECOMPUTE
- Specifies that out-of-date index statistics are not automatically recomputed.
- ON filegroup1
- Creates the specified index on the given filegroup1.
An INDEX is created using the CREATE INDEX command.
Indexes may be:
- Clustered Index
- Columns that contain a limited number of distinct values, such as a state column that contains only 50 distinct state codes.
- Queries that return a range of values using operators such as BETWEEN, >, >=, <, and <=.
- Columns that are accessed sequentially.
- Queries that return large result sets.
- Columns that are frequently accessed by queries involving join or GROUP BY clauses; typically these are foreign key columns.
- OLTP-type applications where very fast single row lookup is required, typically by means of the primary key.
- Columns that undergo frequent changes.
- Covered queries. The more columns within the search key, the greater the chance for the data in the indexed column to change, resulting in additional I/O.
- Columns that contain a high number of distinct values, such as a combination of last name and first name (if a clustered index is used for other columns).
- Queries that do not return large result sets.
- Columns frequently involved in search conditions of a query (WHERE clause) that return exact matches.
- Decision Support System applications for which joins and grouping are frequently required.
- Covered queries.
- If CLUSTERED is not specified, a nonclustered index is created.
- Index names must be unique within a table but need not be unique within a database.
- Index names must follow the rules of identifiers.
- Only the owner of the table can create indexes on the same table.
A clustered index actually stores the data records in physical order. Because a table can only be physically sorted in one order, a table can only define one clustered index. Having a clustered index also means that each time a record is inserted or deleted from a table, the table or at least parts of the table must be rewritten to maintain the physical order. Even an update to the key field of a clustered index causes the table to delete the 'old' record and then insert the 'new' record. Obviously maintaining the physical order of the records in a table can be quite expensive, especially if there are frequent updates to the table. However, if the table is used mostly for retrieval and reporting, the advantages of a clustered index come to the forefront.
Clustered Indexes are suitable for:
A nonclustered index creates a separate 'internal' table that stores only the selected key values of the table in order. Each 'record' in this index contains the key value from one record in the table along with a pointer to either the data record itself or to a value in the clustered index. Because a nonclustered index does not require a physical sorting of the actual data, we can have as many nonclustered indexes associated with a single table as possible. The maximum limit is 249. For each insert, delete, and update performed, SQL updates the table.
Nonclustered Indexes are suitable for:
An index in which no two index values are the same is called a unique index. Sql Server checks for duplicate values when a unique index is created and each time data is subsequently added. If duplicate values exist, then an error message is generated. Unique indexes cannot be created on columns that already contain duplicate values.
Fillfactor
Fillfactor allows us to reserve free space on each page of the index. Fillfactor is a value from 1 through 100 that specifies the percentage of the index page to be left empty. If we do not use the fillfactor option and an index page fills up, SQL Server must take time to move half the index page to a new page to make room for new rows (Page Split). This operation is quite expensive. For update-intensive tables, a properly chosen fillfactor value yields better update performance than an improper fillfactor value. If no value is specified the default value for the fillfactor is 0.
Examples
Code:
CREATE CLUSTERED INDEX Index_Name_Clstd ON Students(Name);
Output:
Index (Id = 2) is being rebuilt.
Explanation:
In the above example, we have built a clustered index, Index_Name_Clstd, on the 'Name' column of the 'Students' table.
Language(s): MS SQL Server
Code:
CREATE NONCLUSTERED INDEX Index_Name_NonClstd ON Students(Name);
Output:
The command(s) completed successfully.
Explanation:
In the above example, we have built a nonclustered index, Index_Name_NonClstd, on the 'Name' column of the 'Students' table.
Language(s): MS SQL Server
Code:
CREATE UNIQUE INDEX Index_Name_Unique ON Students (Name);
Output:
The command(s) completed successfully.
Explanation:
The above example creates a unique index, Index_Name_Unique, on the 'Name' column of the 'Students' table.
Language(s): MS SQL Server
Code:
CREATE CLUSTERED
INDEX Index_Name_Clstd_FF10 ON Students (Name)
WITH FILLFACTOR=10;
Output:
Index (Id = 2) is being rebuilt.
Index (Id = 3) is being rebuilt.
Index (Id = 4) is being rebuilt.
Index (Id = 2) is being rebuilt.
Index (Id = 3) is being rebuilt.
Index (Id = 4) is being rebuilt.
Explanation:
In the above example, we have built a new clustered index on the 'Name' field of the 'Students' table with a fillfactor of 10.
Note: Drop any of the existing CLUSTERED INDEX using the DROP INDEX command.
Language(s): MS SQL Server
Creating an Index
- Syntax:
- CREATE [ UNIQUE ] INDEX index ON table (field [ASC|DESC][, field [ASC|DESC], ...]) [WITH { PRIMARY | DISALLOW NULL | IGNORE NULL }]
The CREATE INDEX statement is used to index one or more fields in an existing table.
You can do this by giving the index a name, and by stating the table and field(s) to which the index will apply.
Examples
Code:
CREATE INDEX CustomerIndex ON Customers (Name);
Explanation:
This example creates a simple index on the Name field of the Customers table:
Language(s): MS SQL Server
Code:
CREATE INDEX CustomerIndex ON Customers (Name DESC, City);
Explanation:
By default, the values in a field are indexed in ascending order, but if you want to index them in descending order, you can add the reserved word DESC. You can also index more than one field simply by listing the fields within parentheses.
Language(s): MS SQL Server
Code:
CREATE UNIQUE INDEX CustomerIndex ON Customers (Name);
Explanation:
If you want to prohibit duplicate values in the indexed field or fields, you can use the reserved word UNIQUE.
Code:
CREATE UNIQUE INDEX CustomerIndex ON Customers (Name) WITH DISALLOW NULL;
Explanation:
The optional WITH clause allows you to enforce further data validation rules by using three options: With the DISALLOW NULL option you can prohibit NULL entries in the indexed field(s).
Language(s): MS SQL Server
Code:
CREATE UNIQUE INDEX CustomerIndex ON Customers (Name) WITH IGNORE NULL;
Explanation:
With the IGNORE NULL option you can exclude records with NULL values in the indexed field(s) from the index.
Language(s): MS SQL Server
Code:
CREATE UNIQUE INDEX OrderIndex ON OrderDetailsODBC (OrderID);
Explanation:
You can also use CREATE INDEX to create a pseudo index on a linked table in an ODBC data source, such as SQL SERVER Note however, that this will only work if the table does not already have an index. You do not need permission or access to the remote server to create the pseudo index, and the remote database will be unaware of and unaffected by the operation.
Note:
Microsoft warns, "The Microsoft Jet database engine doesn't support the use of any DDL statements with databases produced by any other database engine. Use the DAO (Data Access Objects) Create methods instead."
Language(s): MS SQL Server
Code:
CREATE INDEX CustomerIndex ON Customers (CustomerID) WITH PRIMARY;
Explanation:
While the PRIMARY option allows you to designate which indexed field or fields to be the primary key (since primary keys are always unique, there's no need to include the reserved word UNIQUE).
Note that you cannot use the reserved word PRIMARY to create an index on a table that already has a primary key.
Language(s): MS SQL Server
Friday, March 5, 2010
Get Table Primary Key Column(s)
Suppose the following MSSQL server problem. We know table name and need to get its Primary Key columns programmatically. In order to do it we will use the following system tables:
- sysobjects - for all user objects.
- sysindexkeys - for indexes and keys.
- syscolumns - for tables columns.
The query will look like so:
SELECT [name]
FROM syscolumns
WHERE [id] IN (SELECT [id]
FROM sysobjects
WHERE [name] = @table_name)
AND colid IN (SELECT SIK.colid
FROM sysindexkeys SIK
JOIN sysobjects SO ON SIK.[id] = SO.[id]
WHERE SIK.indid = 1
AND SO.[name] = @table_name)