I have two databases on my local. I wish to use tsql to script out one of the two databases in its entirety (schema only) and save it in one .sql script. Is this possible for SQL 2012? And if so, how may I go about doing it? I am using GUI to do this right now but want to use tsql query if possible. I can't use any 3rd party tools.
Thank you
UPDATE: I am using the RIGHT CLICK > GENERATE script method right now. I want to avoid that and find a way to generate the database generation tsql script by some way other than using SSMS GUI. Also, I want to script the entire database and not just tables.
You can do it in the following 2 ways.
Use Powershell.
Use the SMO classes, the Scripter class in particular. The GUI Tools are wrappers around this class.
Here's the solution for #1.
Using Powershell to Generate Table-Creation Scripts. By Robert Sheldon on simple-talk.com
Here's a solution for #2.
See this MSDN Example scripting all tables in a database with SMO.
Relevant code below. Change the database name and other details as appropriate.
//Connect to the local, default instance of SQL Server.
{
Server srv = default(Server);
srv = new Server();
//Reference the AdventureWorks database.
Database db = default(Database);
db = srv.Databases("AdventureWorks");
//Define a Scripter object and set the required scripting options.
Scripter scrp = default(Scripter);
scrp = new Scripter(srv);
scrp.Options.ScriptDrops = false;
scrp.Options.WithDependencies = true;
//Iterate through the tables in database and script each one. Display the script.
//Note that the StringCollection type needs the System.Collections.Specialized namespace to be included.
Table tb = default(Table);
Urn[] smoObjects = new Urn[2];
foreach ( tb in db.Tables) {
smoObjects = new Urn[1];
smoObjects(0) = tb.Urn;
if (tb.IsSystemObject == false) {
StringCollection sc = default(StringCollection);
sc = scrp.Script(smoObjects);
string st = null;
foreach ( st in sc) {
Console.WriteLine(st);
}
}
}
}
If you want to script out ALL the DB objects, and not just tables, take a look at the powershell script in this page where it says "Full Script". It takes care of table and relationship dependencies also.
Related
I've been using this table INFORMATION_SCHEMA.ROUTINES which has the routine definition for procs and functions, i was wondering if there is a similar table for create table and create view routines.
I would just skip using INFORMATION_SCHEMA.ROUTINES entirely. Instead look at sys.sql_modules. It has the ddl for everything you are looking for except tables. But my question is why do you need to find the ddl for all these things?
You can use sys.sql_modules to find the definition of views. For tables, one option is SMO objects. The C# example below returns the DDL for a table in the listed database. This will require references to the Microsoft.SqlServer.Management.Sdk.Sfc, Microsoft.SqlServer.Smo, and Microsoft.SqlServer.ConnectionInfo namespaces. System.Collections.Specialized is also used, but only for StringCollection in this example. This can be filtered using the Name property of the Table class as noted below.
//set source server and database using SMO objects
Server srv = new Server(#"YourServer");
//for Windows Authentication
srv.ConnectionContext.LoginSecure = true;
srv.ConnectionContext.StatementTimeout = 600;
Database db = srv.Databases["YourDatabase"];
//configure Scripter for DDL
Scripter script = new Scripter(srv);
ScriptingOptions scriptOpt = new ScriptingOptions();
//this can changed to views, stored procedures, or other objects
foreach (Table t in db.Tables)
{
//check for system objects
//use t.Name to check table name if needed
if (!t.IsSystemObject)
{
StringCollection sc = t.Script(scriptOpt);
foreach (string s in sc)
{
//DDL is here, it can accessed/used as needed
Console.WriteLine(s);
}
}
}
I have saved certain MDX query and I run them using ADOMD.NET. I get CellSet back which I convert into dataset. All this is working fine. Now the DB team has changed the cube structure. They have updated the DimesnionName, Attribute Name etc. Some dimensions got renamed and some got deleted. Becuase of this I am unable to run my saved queries. I want to create a console application, which will take list of keys ([DimensionName].[AttributeName] or [DimensionName].[AttributeName].[MemeberName] format) and it will tell me following keys does not exists.
Please let me know if this is possible programatically. I dont want to check it manually.
Kindly share a link or code which will help me acheive this.
Thank you.
If you're using ADOMD already this should be no problem, just use the metadata queries:
http://msdn.microsoft.com/en-us/library/ms123485.aspx
Alternatively, AMO is nice http://msdn.microsoft.com/en-us/library/microsoft.analysisservices.aspx
I use it in SSIS for processing, you could easily use it in .Net to test existence of elements:
using Microsoft.AnalysisServices;
...
Server server = new Server();
server.Connect(cubeConnectionString);
Database database = server.Databases.FindByName(databaseName);
Cube cube = database.Cubes.FindByName(cubeName);
foreach (MeasureGroup measureGroup in cube.MeasureGroups)
{
foreach (Partition partition in measureGroup.Partitions)
{
...
}
}
foreach (CubeDimension cubeDimension in cube.Dimensions)
{
Dimension dimension = cubeDimension.Dimension;
var dimName = dimension.Name;
...
}
Finding the names in advance for all the elements you need is probably the hard part (And keeping it all up-to-date).
Would it not be easier to fire all the queries at the cube and try to trap the "no such thing" response?
I am new to raven db. I have read the API and try to create a database . It has something like EnsureDatabaseExists function which creates the database if it does not exist. It actually uses DocumentDatabase type to create that database. I use it and it creates the database but I want to use this object directly so that using this object I can directly work with documents. Am i doing right? Or can there be any better approach then this to work with documents.Thank you.
I think you're confusing the database document and querying documents.
The database document is a document on the default database, which just represent a database in RavenDB which is not the default database. It stores some data like the database name and location. You, as a consumer of ravendb as nothing to do with this document. And this has nothing to do with querying any other documents.
Look here in order to learn how to query ravendb for documents. In order to query a specific database, if you work just with that database than you better just specify the database name in the connection string. If you work against multiy databases at once, you can specify the database name that you want when you open a session, store.OpenSession("database-name").
Three methods are available on store.DatabaseCommands.GlobalAdmin.
GetDatabaseNames: lists database names
EnsureDatabaseExists: creates database if it does not exists
CreateDatabase: creates database
Note that DocumentStore.Initialize() already ensures that the database is created. You can pass a boolean false to avoid this behavior.
// init store object, you pass the service URL + the database name
var store = new DocumentStore("http://localhost:8001/databases/MyNewDataBase");
store.Initialize(false);
// most simple thing is:
var dbName = store.DefaultDatabase;
store.DatabaseCommands.GlobalAdmin.EnsureDatabaseExists(dbName);
If you want to check without creating:
// there is a method to list the database names
bool exists = false;
for (int i = 0; i < int.MaxValue; i++)
{
var names = store.DatabaseCommands.GlobalAdmin.GetDatabaseNames(100, i * 100);
if (names.Contains(dbName))
{
exists = true;
break;
}
if (names.Length < 100)
{
// no more databases
break;
}
}
if (exists)
{
// database exists, do something
}
Reference: https://ravendb.net/docs/article-page/3.5/Csharp/client-api/commands/how-to/create-delete-database
I'd like to know if you can recommend any advanced ADO.NET libraries for working with databases.
I've discovered that LINQ-to-Entities is great for pulling data out of databases, but not at all useful for inserting data into databases. Its missing functionality like fast bulk insert, culling of duplicates, and most of the advanced functionality you can achieve with pure SQL.
So: can you recommend some ADO.NET libraries that offer the sorts of advanced functionality that LINQ-to-Entities is missing?
The ADO.net SqlBulkCopy class enables quick, mass upload of records into a table:
DataTable dt = s_EmptyUploadTable.Copy();
foreach (var itm in yourList) {
DataRow row = dt.NewRow();
row["Field1"] = itm.Field1;
row["Field2"] = itm.Field2;
dt.Rows.Add(row);
}
using (SqlConnection cn = new SqlConnection(yourConnectionString)) {
cn.Open();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(cn)) {
bulkCopy.DestinationTableName = "dbo.YourActualSQLServerTableName";
bulkCopy.WriteToServer(dt);
}
cn.Close();
}
You can use LINQ Entity Data Reader to write an IEnumerable list to a database using SQL Bulk Copy behind the scenes. You can use this library to bulk upload the results of a LINQ query straight into the database, because the results of a LINQ query are IEnumerable.
As there are LINQ-to-everything adapters, you can do tricks like use the LINQ to CSV library to grab the data out of a .csv file using a LINQ query, then the LINQ Entity Data Reader to bulk write this data directly into the database.
Case study:
Problem: read a .csv file quickly into a database. The connection to the SQL database is via LINQ-to-Entitys from C#.
Solution 1: Use LINQ to CSV library, construct a LINQ query to pull out the data you want, then write it in using the standard LINQ-to-Entity calls (ctx.AddObject(), ctx.SaveChanges(), etc). Time taken: 30 seconds for 20,000 records, as LINQ ends up generating a query for every single record (slooooow!!!!!).
Solution 2: Use LINQ to CSV library, construct a LINQ query to pull out the data you want into an IEnumerable, use LINQ Entity Data Reader to bulk write this data directly into the target data table. Time taken: 3 seconds for 20,000 records.
Solution 3: Use a a stored procedure with SQL "bulk copy". Time taken: 2 seconds for 20,000 records. However, this solution is quite brittle as it relies on a stored procedure, and SQL bulk copy is just not compatible with some .csv file formats. This method also requires that you use a staging table between the actual target table and the .csv file, to deal with file formatting issues and to help with normalization.
And, here is the source code for solution #2:
static void WriteCSVtoSQLtable()
{
// Step 1: Read .csv file into IEnumerable using LINQ-to-CSV class.
// This section requires "LINQtoCSV" class as described at http://www.codeproject.com/KB/linq/LINQtoCSV.asp
string inputFilePath = #"T:\x.csv";
CsvFileDescription inputFileDescription = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true
};
IEnumerable<MyCustomColumnMappingClass> csvChains = cc.Read<MyCustomColumnMappingClass>(inputFilePath, inputFileDescription);
// Step 2: Now write into the target table on SQL Server.
// This section requires "EntityDataReader" class described at http://archive.msdn.microsoft.com/LinqEntityDataReader.
public static string dbSqlConnectionString = #";Data Source=(local);Initial Catalog=PhiEngine;Integrated Security=True;MultipleActiveResultSets=True";
SqlConnection dbSql(dbSqlConnectionString);
using (var tran = dbSql.BeginTransaction())
{
var csvFile = from p in csvChains
select p;
SqlBulkCopy bc = new SqlBulkCopy(dbSql,
SqlBulkCopyOptions.CheckConstraints |
SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.KeepNulls, tran)
{
BatchSize = 1000,
DestinationTableName = "TStagingTable" // Temporary staging table in database.
};
bc.WriteToServer(csvFile.AsDataReader()); // Extension method .AsDataReader depends on adding the EntityDataReader class to your C# project (see above).
tran.Commit();
}
}
// This class is used by LINQ to CSV to query the .csv file, see "LINQtoCSV" website.
public class MyCustomColumnMappingClass
{
[CsvColumn(Name = "symbol", FieldIndex = 1)]
public string Symbol { get; set; }
[CsvColumn(Name = "date", FieldIndex = 3, OutputFormat = #"MM/dd/yyyy")]
public DateTime Date { get; set; }
}
How can I execute a DDL statement via NHibernate?
To be clear, I don't want to auto-generate my schema from my mapping files. My DDL is stored in plain text files along the lines of:
CREATE TABLE Foo (Bar VARCHAR(10))
GO
CREATE TABLE Hello (World INTEGER)
GO
I want to cycle through these in order and execute each of them. I could just open a SqlConnection and execute via a SqlCommand but I'd like to go through NHibernate if there is a nice way to do this. This is mainly because I want to remain as database agnostic as possible: I have a SQL db now but I might need to implement Oracle or DB2 later...
I'm using .Net v3.51 and NHibernate v2.1. I looked at the NHibernate SchemaExport class but couldn't see a way to use this for this purpose.
I've used session.Connection.CreateCommand and session.Transaction.EnlistCommand before with success to run raw SQL.
Here's a snippet of something similar that I've done:
using (var command = _session.Connection.CreateCommand())
{
_session.Transaction.Enlist(command);
command.CommandText = "select foo from bar where id = #id";
var versionIdParameter = command.CreateParameter();
versionIdParameter.ParameterName = "id";
versionIdParameter.Value = id;
command.Parameters.Add(versionIdParameter);
using(var reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
// ...
}
}
You can get an IDbConnection from an ISession's Connection property but you'll need to do this with SqlCommand. Executing DDL is outside of NHibernate's scope.