I'm trying to update a value of document created on cosmosDB azure using sql api. The problem is that the requests update/ delete/ Insert don't work.
client.queryDocuments(
collectionUrl,
UPDATE tableC
SET prev = 12
WHERE condition
).toArray((err, results) => {
if (err) res.json({ 'A': 12 });
else {
res.json({ 'A': 15});
}
})
CosmosDB SQL is not ANSI SQL implementation. It supports just querying in a somewhat similar manner, but it's not the same thing.
From Introduction to Azure Cosmos DB: SQL API:
Azure Cosmos DB supports querying documents using a SQL language,
which is rooted in the JavaScript type system, and expressions with
support for relational, hierarchical, and spatial queries. The Azure
Cosmos DB query language is a simple yet powerful interface to query
JSON documents. The language supports a subset of ANSI SQL grammar
and adds deep integration of JavaScript object, arrays, object
construction, and function invocation.
So basically CosmosDB takes some syntax rules and conventions from SQL but when you look closer it's another beast. Ansi SQL contains things CosmosDB SQL API does not have and cosmosDB SQL has things ANSI SQL does not have.
Why?
Not having support for entire ANSI SQL makes sense, as SQL was designed for relational data manipluation needs. CosmosDB is not a relational database and its change model is working with documents as the changeable units, not individual fields or sets. In DoucmentDB you add one entire document, update one entire document, or delete one entire document. As long as this stands, it does not need the complexity of traditional SQL insert/update/delete syntax.
CosmosDB's flavor of SQL only supports querying.
You cannot use data manipulation SQL.
My code and the Linq to sql function SubmitChanges are working, but when using a local database a copy of the database in the bin folder is updated and not the primary database. So the changes aren't shown on a new query. If I re-connect the database but don't load it as local same problem - the primary database isn't updated, but now I can't figure out which one is (tks to this question).
What setting for a local db or how do I use a non-local database to show changes on a new query of the database?
Dim DATA As New lnqPolarisDataContext
Dim newBOOK As New BOOK()
newBOOK.ID = 14
newBOOK.LEG = 11
newBOOK.P_C = "C"
newBOOK.STRATEGY = "STRADDLE"
newBOOK.STRIKE = 999
newBOOK.CONTRACT = "XXX"
DATA.BOOKs.InsertOnSubmit(newBOOK)
DATA.SubmitChanges()
... new query doesn't show these changes
maybe this is the best method?
The real solution in my opinion would be to put your database on the server where it belongs - after all, SQL Server is a server-based solution, not a file-based "database".....
install SQL Server Express (and you've already done that anyway)
install SQL Server Management Studio Express
create your database in SSMS Express, give it a logical name (e.g. YourDatabase)
connect to it using its logical database name (given when you create it on the server) - and don't mess around with physical database files and user instances. In that case, your connection string would be something like:
Data Source=.\\SQLEXPRESS;Database=YourDatabase;Integrated Security=True
and everything else is exactly the same as before...
Also see Aaron Bertrand's excellent blog post Bad habits to kick: using AttachDbFileName for more background info.
I'm facing a problem with EF against Azure DB secondary connection. Here is my problem:
I'm using EF 6 with code first
I already setup a primary Azure DB with 2 Active GEO-Replicated secondary database (have difference server and db name as well as login account)
I use EF6 to manipulate the primary Azure DB. The case is that if the primary DB is down (by any reason) and I want to switch to the active secondary dbs for select statements at runtime. How can I achieved that?
Notes: For example, I have the code snippet below:
using (AppContext context = new AppContext()) // AppContext is derived from DbContext and using the primary connection string
{
var users = await context.Users.ToListAsync(); // If this line of code failed with the primary connection string
}
I want to auto-switch dynamically to the secondary db if the line var users... is failed at runtime. Any recommendation?
Thanks for your help!
I want something like :
insert into server2.database1.table1 select * from server1.database1.table1
both tables are exactly the same.
how can I Copy data between two server instances?
SQL - Linked Server
If both servers are SQL Server, you can set up Linked servers - I would suggest using an SQL account for security there.
Then you can simply perform
insert into server2.database1.dbo.table1
select * from server1.database1.dbo.table1 where col1 = 'X'
If you run the query in SQL Management studio connected to server1, and current database set to database1, you won't need the prefix
server1.database1.dbo.
Also, the linked server would be configured on server1, to connect to server2 (rather than the other way around).
If you have the correct OLE DB drivers, this method can also work between different types of RDBMS (ie. non-SQL Server ones).
Open Query
Note: Beware not to rely on linked servers too much especially for filtering, and for joins across servers, as they require data to be read in full to the originating RDBMS before any conditions can be applied. Many complications can arise from Linked Servers, so read up before you embark, as even version differences might cause headaches.
I recommend you use the OPENQUERY command for SQL Servers to get around such limitations. Here's an example, but you should find help specific to your needs through further research:
insert into server2.database1.dbo.table1
select * from OPENQUERY(server1, 'select * from database1.dbo.table1 where col1 = ''X''');
The above code is more efficient, filtering the data on the source server (and using available indexes), before pumping the data through, saving bandwidth/time/resources of both the source and destination servers.
(Also note the double quote '', is an escape sequence to produce a single quote.)
SQL - Temporarily on the same server
Would enable (note the underscore):
insert into server2_database1.dbo.table1
select * from database1.dbo.table1
Still within the SQL query domain. If you can temporarily move the database on server2 to server1, then you won't need the linked server. A rename of the database would appear to be required while co-locating on server1. Achieving such co-location could use various methods, I suggest shrinking database files before proceeding with either:
Backup/Restore - Backup on server2, Restore on server1 (with different name) - perform insert as described above, but without the server1 or server2 prefixes. Then reverse - backup on server1, restore on server2/
Detach/Attach - Rename database, Detach on server2, (compress), copy files to server 1, (decompress), attach on server1, perform insert. Then reverse...
In either case, SQL Server version could be a barrier. If server1 is of a lower SQL version, then both backup and detach/attach methods will likely fail. This can be worked around by moving the server1 database to server2, which may or may not be more suitible.
Other Methods
May be suitable, non-SQL/TSQL method failing favorable environmental factors for previously mentioned methods. And if you have the correct access (OLE DB Drivers, etc..), this method can also work between different types of RDBMS (ie. non-SQL Server ones), and data-sources (such as XML, flatfiles, Excel Spreadsheets...)
SSIS Explicitly with Business Development Management Studio - direct datapump or using delimited file intermeditary.
SSIS Implicitly through SQL Management Studio, by right clicking the database1 on server1 > Tasks > Export, then completing the wizard. May work direct to server2, or using a flat-file intermeditary.
.Net Programming with SqlBulkInsert (I believe the SSIS datapump uses such an object), I can go into more detail about this, if it interests you.
Eg. of SQLBulkInsert (psedo-C# code)
SqlConnection c = new SqlConnection("connectionStringForServer1Database1Here");
SqlConnection c2 = new SqlConnection("connectionStringForServer2Database1Here");
c.Open();
SqlCommand cm = new SqlCommand(c);
cm.CommandText = "select * from table1;";
using (SqlDataReader reader = cm.ExecuteReader())
{
using (SqlBulkInsert bc = new SqlBulkInsert(c))
{
c2.Open();
bc.DestinationTable = "table1";
bc.WriteToServer(reader);
}
}
Pretty cool huh? If speed/efficiency is a concern - SqlBulkInsert based approaches (Such as SSIS) are the best.
Update - Modifying the destination table
If you need to update the destination table, I recommend that you:
Write to a staging table on the destination database (a temporary table, or proper table which you truncate before and after process), the latter is preferable. The former may be your only choice if you don't have CREATE TABLE rights. You can perform the transfer using any one of the above options.
Run a MERGE INTO command as per your requirements from the staging table to the destination table. This can Insert, Update and Delete as required very efficiently.
Such a whole process could be enhanced with a sliding window (changes since last checked), only taking recently changed rows in the source an applying to the destination, this complicates the process, so you should at least accomplish the simpler one first. After completing a sliding window version, you could run the full-update one periodically to ensure there are no errors in the sliding window.
To copy data between two different servers you have several options:
Use linked servers.
Use the data import export wizard.
Use a third party tool such as Red Gate SQL Data Compare.
Similar to Todd C# SqlBulkCopy
Generally this is easier than creating linked servers.
Create a unit test and run the below, if you have triggers then be careful and you will need ALTER permissions.
[Test]
public void BulkCopy()
{
var fromConnectionString = #"fromConnectionString";
var destinationConnectionString = #"destConnectionString2";
using (var testConnection = new SqlConnection(fromConnectionString))
{
testConnection.Open();
var command = new SqlCommand("select * from MyTable;", testConnection);
using (var reader = command.ExecuteReader())
{
using (var destinationConnection = new SqlConnection(destinationConnectionString))
{
using (var bc = new SqlBulkCopy(destinationConnection))
{
destinationConnection.Open();
bc.DestinationTableName = "dbo.MyTable";
bc.WriteToServer(reader);
}
}
}
}
}
}
The best way to do this would be to create a "linked server".
And then you can use below statement into your insert statement in order to define your table
[linkedserver].databasename.dbo.tablename
On Server A add a linked server (B)
http://msdn.microsoft.com/en-us/library/ms188279.aspx
Then you can transfer data between the two.
Export table data from one SQL Server to another
HTH
First You need to add the server
Eg. Server 1 and Server 2
sp_addlinkedserver 'Server-2'
then copy your data from that server to your server by using following query
In Server-1 Write
select * INTO Employee_Master_bkp
FROM [Server-2].[DB_Live].[dbo].[Employee_Master]
If you need an alternative without using Linked Servers, my favorite option is use the command line BCP utility.
With this bulk copy tool, you can export the data to a flat file, copy the file across the network and import it (load it) onto the target server.
https://learn.microsoft.com/en-us/sql/tools/bcp-utility
I have just started working for a new company where I am regularly having to query 8 different servers (all Microsoft SQL 2005 servers). At the moment every morning I am connecting to each server individualy every morning to read the latest entry in a [application].[tmpLogs] table. I have to use different users names and password for each server. I want to write a Linq or SQL query that I can just run in LinqPad to get the last row entered in the tmpLogs table on each server. Does anyone know how I can connect to all the servers and query the tables in one query?
Do the tmpLogs tables have the same columns on each server? If so, you can take advantage of the fact that LINQPad lets you create new typed DataContexts with different connection strings.
Just connect to just one of your databases, and do this:
// Dump the log for the current database:
TmpLogs.OrderByDescending (l => l.Date).First().Dump();
// Dump the logs for other databases:
string[] otherConnectionStrings =
{
"server=...database=....etc",
"server=...database=....etc",
...
}
foreach (string cxString in otherConnectionStrings)
{
var dc = new TypedDataContext (cxString);
dc.TmpLogs.OrderByDescending (l => l.Date).First().Dump();
}
You could choose one SQL Server as your 'master' server. Then set up the other servers as LINKED Servers (see http://msdn.microsoft.com/en-us/library/ms188279.aspx). You could configure a LINQ to SQL object to connect to the LINKED servers via the 'master' server.
You could also just take this out of LINQ and set up scheduled tasks to push the data into a 'warehouse' table periodically. It's easier to communicate with LINKED servers via Stored Procedures than it is via LINQ. As far as I know, LINQ doesn't contain the concept of DB catalogs, only tables. The catalogs are abstracted out in the DataContext object, which if you're using Linqpad, doesn't exist.