I've a C# 4.0 console application and a SQL Server 2008 database up and running on database server.
Does somebody know if there is a way to get the database properties (like "Database Read-Only" ) from the C# code?
My guess is it should be, but I was not able to find out the accurate solution.
Thanks in advance
There are at least two ways to do it. One is to use the Database Metadata tables the other to use SQL Management objects in both cases there's lot of data there so you really need to know what you want. For example this is how you would get the "Database Read-Only" property you mentioned.
Using a SqlCommand against the MetaData
using (SqlConnection cnn = new SqlConnection("Data Source=.;Initial Catalog=master;Integrated Security=SSPI;"))
{
SqlCommand cmd = new SqlCommand("SELECT is_read_only FROM sys.filegroups",cnn);
cnn.Open();
var isReadOnly = cmd.ExecuteScalar();
Console.WriteLine(isReadOnly );
}
Using SMO
using System;
using Microsoft.SqlServer.Management.Smo;
namespace SMO_Test
{
class Program
{
static void Main(string[] args)
{
Server srv = new Server(); //Connection to the local SQL Server
Database db = srv.Databases["master"];
foreach (FileGroup fg in db.FileGroups)
{
Console.WriteLine(fg.ReadOnly);
}
}
}
}
Related
I'm building an ssis package and I wish to use an existing OleDbConnection inside the Script Component. Here is my code:
public override void AcquireConnections(object Transaction)
{
base.AcquireConnections(Transaction);
cm = this.Connections.Connection;
con = (OleDbConnection)cm.AcquireConnection(Transaction);
MessageBox.Show(con.ToString());
}
When I close BIDS, i get the following message:
"System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to class type 'System.Data.OleDb.OleDbConnection'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface."
The same code works fine with an Ado.Net connection. Can I use OleDbConnection here or Script Component only supports Ado.Net?
Thanks in advance.
As mentioned in the MSDN
You cannot call the AcquireConnection method of connection managers that return unmanaged objects, such as the OLE DB connection manager and the Excel connection manager, in the managed code of a Script task.
You need to use the ADO.NET connection manager if you want to use Aquire Connection method
in order to use OLEDB connection add a reference to Microsoft.SqlServer.DTSRuntimeWrap and try the below code
ConnectionManager cm = Dts.Connections["oledb"];
IDTSConnectionManagerDatabaseParameters100 cmParams =
cm.InnerObject as IDTSConnectionManagerDatabaseParameters100;
OleDbConnection conn = cmParams.GetConnectionForSchema() as OleDbConnection;
MSDN Link
Just in case someone googled this and couldn't find a real solution, you have to override the AcquireConnections, PreExceute and ReleaseConnections methods in order to use an OleDbConnection. The trick is the ConnectionString property:
OleDbConnection con;
OleDbCommand cmd;
IDTSConnectionManager100 connMgr;
/*Here you prepare the connection*/
public override void AcquireConnections(object Transaction)
{
base.AcquireConnections(Transaction);
connMgr = this.Connections.YourConnName;
con = new OleDbConnection(connMgr.ConnectionString);
}
/*Here you prepare the sql command and open the connection*/
public override void PreExecute()
{
base.PreExecute();
cmd = new OleDbCommand("Some Select", con);
cmd.CommandType = CommandType.Text;
con.Open();
}
/*Here you execute your query for each input row*/
public override void Entrada0_ProcessInputRow(Entrada0Buffer Row)
{
OleDbDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
/*Do your stuff*/
}
}
/*And here you release the connection*/
public override void ReleaseConnections()
{
base.ReleaseConnections();
connMgr.ReleaseConnection(con);
}
HTH
Thanks praveen.
I found the relevant part in your link:
"If you must call the AcquireConnection method of a connection manager that returns an unmanaged object, use an ADO.NET connection manager. When you configure the ADO.NET connection manager to use an OLE DB provider, it connects by using the .NET Framework Data Provider for OLE DB. In this case, the AcquireConnection method returns a System.Data.OleDb.OleDbConnection instead of an unmanaged object. To configure an ADO.NET connection manager for use with an Excel data source, select the Microsoft OLE DB Provider for Jet, specify an Excel file, and enter Excel 8.0 (for Excel 97 and later) as the value of Extended Properties on the All page of the Connection Manager dialog box."
Thanks!
The code below serves to change connection string in App.config at runtime, I found it here but this code did not work for me on Visual Studio 2010 and SQL Server 2008, I could not open the connection to the Northwind database.
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;
using System.Xml;
namespace MyNameSpace
{
public partial class FrmConnectionTest : Form
{
public FrmConnectionTest()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
//Constructing connection string from the inputs
StringBuilder Con = new StringBuilder("Data Source=");
Con.Append(TxtServer.Text);
Con.Append(";Initial Catalog=");
Con.Append(TxtDatabase.Text);
Con.Append(";Integrated Security=SSPI;");
string strCon = Con.ToString();
updateConfigFile(strCon);
//Create new sql connection
SqlConnection Db = new SqlConnection();
//to refresh connection string each time else it will use previous connection string
ConfigurationManager.RefreshSection("connectionStrings");
Db.ConnectionString = ConfigurationManager.ConnectionStrings["con"].ToString();
//To check new connection string is working or not
SqlDataAdapter da = new SqlDataAdapter("select * from employee");
DataTable dt = new DataTable();
da.Fill(dt);
CmbTestValue.DataSource = dt;
CmbTestValue.DisplayMember = "EmployeeID";
}
catch (Exception E)
{
MessageBox.Show(ConfigurationManager.ConnectionStrings["con"].ToString() + ".This is invalid connection", "Incorrect server/Database");
}
}
public void updateConfigFile(string con)
{
//updating config file
XmlDocument XmlDoc = new XmlDocument();
//Loading the Config file
XmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
foreach (XmlElement xElement in XmlDoc.DocumentElement)
{
if (xElement.Name == "connectionStrings")
{
//setting the coonection string
xElement.FirstChild.Attributes[2].Value = con;
}
}
//writing the connection string in config file
XmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
}
}
}
Using Visual Studio 2010 and SQL Server2008, I got 2 errors for the next line:
SqlDataAdapter da = new SqlDataAdapter("select * from employee");
Error 1 The best overloaded method match for 'System.Data.SqlClient.SqlDataAdapter.SqlDataAdapter(System.Data.SqlClient.SqlCommand)' has some invalid arguments
Error 2 Argument 1: cannot convert from 'string' to 'System.Data.SqlClient.SqlCommand'
Is there any solution to this issue? Thank you.
The error is telling you that you are passing incorrect parameters to your SqlDataAdapter. I think the proper call would be:
SqlDataAdapter da = new SqlDataAdapter("select * from employee", Db);
Edit
It looks like you're creating your connection string from within your program, saving it to your config file, then reading it out of our config file right before you create your SqlDataAdapter. So, when you debug this line:
Db.ConnectionString = ConfigurationManager.ConnectionStrings["con"].ToString();
Double check that Db.ConnectionString actually contains a connection string.
The other thing to do is open up your SQL Server Management Studio and confirm you can connect to the Northwind database from there. Including/alternatively, in Visual Studio, open your "Server Explorer" window and confirm you can create a Data Connection to Northwind by clicking Add Connection and then setting the connection property window to your server and dropping down the combobox to see if it populates with your databases:
Take a look at the available constructors of the SqlDataAdapter class.
There is no constructor overload that accepts just an SQL String.
You need to use one of the other overloads.
For example, there is one that needs an SQL String and a SqlConnection object.
To use it, change your code like this:
SqlDataAdapter da = new SqlDataAdapter("select * from employee", Db);
EDIT:
As BradRem already mentioned in his comment, try a different connection string.
If his example doesn't work for you, you can find more possible examples at http://connectionstrings.com/sql-server-2008.
Do you really have a database called Northwind on your server?
Does the Windows user on your current machine have permissions on the server to access the database? (that's what Integrated Security=SSPI means - your current Windows user is used to access the database!)
I'd quite like to use ADO.NET to generate a CREATE TABLE script to create an exact copy of a given table.
The reason for this is persistence testing. I would like to know whether my application will persist to a particular database. I would like to be able to point the app to the database and table in question, and then the app will generate a new database with an exact copy of the specified table. Thus, persistence testing can take place against the cloned table without touching the original database, and when I'm done the new database can simply be dropped.
Before I embark on this ambitious project, I would like to know if anything already exists. I've tried Google, but all I can find are ways to get schema generation SQL through the SSMS UI, not through code.
You can use SQL Management Objects (SMO) for this.
Example (C#)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SqlServer.Management.Smo;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Server srv = new Server(#".\SQLEXPRESS");
Database db = srv.Databases["MyDB"];
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.
Microsoft.SqlServer.Management.Sdk.Sfc.Urn[] smoObjects = new Microsoft.SqlServer.Management.Sdk.Sfc.Urn[1];
foreach (Table tb in db.Tables)
{
smoObjects[0] = tb.Urn;
if (tb.IsSystemObject == false)
{
System.Collections.Specialized.StringCollection sc;
sc = scrp.Script(smoObjects);
foreach (string st in sc)
Console.WriteLine(st);
}
}
Console.ReadKey();
}
}
}
Using SQL ManagementStudio 2008 I created SQL 3.5 Compact DB (TestCompact.sdf) and I have created subscription to existing Publication. Using SQL Management Studio it is working. I have transfered TestCompact.sdf to Windows Mobile 5 emulator device and with QueryAnalyzer for Mobile I could query existing tables in TestCompact.sdf. I don't know how to start replication synchronization on that mobile device. Do I need to write some C# code or it is possible do it more simple?
EDIT: (Added after reply on my question)
Maybe it will be useful for someone what C# code did the job for me:
(Using SQL Management Studio - Properties on existing subscription for my Compact DB) I read what are values for a replObj properties)
private void btnSync_Click(object sender, EventArgs e)
{
SqlCeConnection sqlCeConn = null;
SqlCeReplication replObj = new SqlCeReplication();
string connString = #"data source=\My Documents\TestReplicationCompactDB.sdf;Password=bero";
replObj.InternetUrl = #"http://192.168.99.99/VirtualDirectoryForCompactDBReplication/sqlcesa35.dll";;
replObj.PublisherDatabase = "TestReplicationDB";
replObj.PublisherSecurityMode = SecurityType.NTAuthentication;;
replObj.Publisher = #"DBTESTSRV\SQL2008";
replObj.Publication = "TestReplication2";
replObj.Subscriber = "TestReplication";
replObj.SubscriberConnectionString = #"data source=\My Documents\TestReplicationCompactDB.sdf;Password=bero";
replObj.InternetLogin = #"ares\intor";
replObj.InternetPassword = "intor";
try
{
sqlCeConn = new SqlCeConnection(connString);
sqlCeConn.Open();
replObj.Synchronize();
sqlCeConn.Close();
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
if (sqlCeConn != null && sqlCeConn.State == ConnectionState.Open)
sqlCeConn.Close();
return;
}
string countPublisherChanges = replObj.PublisherChanges.ToString();
string countSubScriberChanges = replObj.SubscriberChanges.ToString();
MessageBox.Show(String.Format("Finished with {0} subscriber changes and with {1} publisher changes", countSubScriberChanges, countPublisherChanges));
}
You need to write "some" C# code, at the end of the Wizard in SSMS you get some sample code.
Not able to import application definition file!! Error: The metadata object with Name 'XYZ' and of Type 'LobSystemInstance' has a Property with Name 'DatabaseAccessProvider' that has either an invalid value or Type. Error was encountered at or just before Line: '10' and Position: '10'.
line 10 in ADF:
<"Property Name="DatabaseAccessProvider" Type="System.String">SqlOledb<"/Property>
Please give me ideas on how to display data from SQL Server 6.5 in Sharepoint?
The value of the node is invalid. You need to use SqlServer or OleDb. Check out this page for more information:
http://msdn.microsoft.com/en-us/library/ms550725(office.12).aspx
Im just starting on a similar task (so I found your unanswered question). I am trying to copy our documentation library in Sharepoint to an SQL db. Its not opening your file directly from SQL its using some c# code to setup a job which opens the sharepoint which may be what you are wanting.
There are two methods I have found so far:
One is to copy your data from sharepoint to a linked list in Access and then use the OLEDB methods in to open it.
Found here: C# Sync MS Access database to sql server
private static void BulkCopyAccessToSQLServer
(CommandType commandType, string sql, string destinationTable)
{
string connectionString = #"C:\Migration\Sharepoint Access SQL Batch Job\Database11.accdb";
using (DataTable dt = new DataTable())
{
string ConnStr = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Migration\Sharepoint Access SQL Batch Job\Database11.accdb;Jet OLEDB:Database Password=password";
//using (OleDbConnection conn = new OleDbConnection(Settings.Default.CurriculumConnectionString))
using (OleDbConnection conn = new OleDbConnection(ConnStr))
using (OleDbCommand cmd = new OleDbCommand(sql, conn))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(cmd))
{
cmd.CommandType = commandType;
cmd.Connection.Open();
adapter.SelectCommand.CommandTimeout = 240;
adapter.Fill(dt);
adapter.Dispose();
}
using (SqlConnection conn2 = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString))
using (SqlConnection conn2 = new SqlConnection(connectionString))
{
conn2.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(conn2))
{
copy.DestinationTableName = destinationTable;
copy.BatchSize = 1000;
copy.BulkCopyTimeout = 240;
copy.WriteToServer(dt);
copy.NotifyAfter = 1000;
}
}
}
}
The other is to use the Microsoft.Sharepoint libraries and open your sharepoint directly from the c# then copy it into your SQL.
Found here: http://www.dotnetspark.com/kb/3573-fetching-lists-from-sharepoint-2010-site.aspx
using (SharePointclientObj.ClientContext ctx = new SharePointclientObj.ClientContext(clientContext))
{
//Get the site
SharePointclientObj.Web site = ctx.Web;
ctx.Load(site);
//Get Lists
ctx.Load(site.Lists);
//Query
ctx.ExecuteQuery();
//Fill List
foreach (SharePointclientObj.List list in site.Lists)
{
Console.WriteLine(list.Title);
}
}