Wednesday, January 18, 2017

Fastest way to create and distribute a dynamic report from SQL Server

From request to delivery in 5 minutes or less! xSQL RSS Reporter for SQL Server enables you to generate standard Atom or RSS feeds containing any data that you are authorized to pull from a SQL Server database. The concept is very simple, you write a query that will be executed against a database and if the query executes successfully, RSS Reporter will automatically provide the output of that query in a standard Atom or RSS feed format that can be consumed from any device, anywhere. All that's left to do is send the url link to the individuals you wish to distribute the report to - every time they they open that report they will see the current data which can also be refreshed on demand. They can also filter and sort the report as they wish.

Here is a screen shot showing how you can define the feed/ report:

Download now and see what you have been missing!

Wednesday, January 11, 2017

Tables can't be compared

"I am trying to compare two databases and xSQL Data Compare has marked all table pairs with a red X and the messages on the output window show something like [16:08:11] Session [New Compare* (2)]: Pair [dbo].[MyTable] - [dbo].[MyTable] can't be compared. - what am I doing wrong?"

This is more or less a typical email we receive quite often from our users. The answer is, you are not doing anything wrong, but whoever designed that database didn't do a great job!

When comparing two database the xSQL Data Compare first reads the list of tables and views as well as their definitions and performs an automatic pairing of the tables and views based on names. There are certain mapping rules that allow the user to configure the mapping but by default it pairs them based on a simple name match. It then pairs the columns from both tables on each table pair and last but not least, it identifies the candidate comparison keys and decides which one to use. A candidate comparison key must uniquely identify each row on the table, so the ideal comparison key would be the Primary Key of the table but a unique index would be ok too. When it does not find a candidate key for a table pair it marks the pair as "non-comparable" since it has no way to match rows to each other. All tables in your database should have a primary key. However, if you find yourself in charge of a database that does not have primary keys defined don't despair - with a little bit of extra work you can still compare those tables. The xSQL Data Compare allows you to manually select comparison keys for each table pair:
 

To manually define the comparison keys for a table pair, drill down on that pair (click on the ... button on the left of the pair) and on the window that appears click on the "Unique Keys" tab. Choose one or more columns that you know form a unique key for the table and select that combination of columns as the comparison key. You will need to go through this exercise for all table pairs that are shown as non-comparable so it's a bit tedious however, once you have done this xSQL Data Compare will remember and the next time you need to compare those databases you will not see the can't compare message anymore.

xSQL Data Compare supports all SQL Server versions from SQL Server 2000 to SQL Server 2016 as well as SQL Server Azure, and it's free for SQL Server Express edition. Download now and see for yourself why thousands of users love it!

Documenting databases

Open any book or article about database development and administration, and I can all but guarantee that you will find a section for database documentation that describes its importance, best practices, conventions, etc. Why is this? How come so much attention is given to an aspect of databases that, at first sight, has nothing to do with their functionality? Those sections in books and articles, provide dozens of arguments in favor of the importance of database documentation, almost too much to remember. However, most of the reasons boil down to the following:
  • An environment that is less complex.
  • Lower likelihood of errors
  • Databases that are easy to maintain and troubleshoot
  • Low training cost for new staff
  • Higher productivity 
It also offers a common language between IT and business decision makers, and an easy way to find hot spots or areas that are troublesome and could potentially become bottlenecks for the database.

Even though the high importance of documentation is stated and repeated over and over, and is just blatantly obvious, the process of documenting databases is often postponed or overworked by DBAs or developers (myself included). Why? Well, because it is simply too boring. Most DBAs would prefer to perform virtually any other task instead of typing in the descriptions of every element, one by one, in a Word or HTML document. If only there was some kind of tool that would do this instead of having to spend precious human work hours on it. But wait, there is! So we arrive at the goal of this article, to demonstrate how xSQL Documenter reads databases and generates those databases' documentation in Compiled HTML Help document and HTML files. 

For this demo, I'm using the AdventureWorks2012 sample database for the simple reason of it being a very well documented database. The process is fairly straightforward. First, you specify the databases you want to document by supplying the connection strings. xSQL Documenter supports all of the popular database engines such as SQL Server, MySQL, Oracle, DB2 etc. (for a full list, have a look here)

Choose the objects in those databases that you want documented:


And then press 'GO'. xSQL Documenter will read each object's type, descriptions (in the case of SQL Server it will read the MS_Description field), relationships with other database objects, and just about any other information it can find about the object. Then, it will use all the information gathered to build the help files. These help files will be saved by default in an 'output' folder on the same location as xSQLDocumenter.exe and will have the following format:



 As you can see, the information is grouped first by database, then by object type, and then by schema. Clicking on any object type will display a list of all the objects of that type along with some other data for each object. These data differ for every object type. For example, for tables, it will display the number of columns, indexes, constraints, number of objects it refers to and objects that refer to it and a comment which is taken from the MS_Description field. For views, it will display the number of columns, code length, number of dependents (like indexes), number of objects the view depends on, the row size and a comment, again taken from MS_Description. If you click on any object a new page will open with detailed information about each column in the table.

Below is the detailed view of the documentation for the Employee table.

First it displays a description and data for all the columns, these data include the column's data type, default value, whether it is nullable or not, a description, etc. Further down, you can also see details about the indexes and a list of all the objects that reference the Employee table and object which this table references.


 At the end of the page you can see a chart showing the relations among objects. Keep in mind that all objects above the Employee table in the chart are objects that are referenced by this table and all objects below it are objects that reference this table. Besides this chart you also see detailed information about all the constraints and foreign keys for the Employee table.


 As demonstrated, with just a few clicks you can generate a full and comprehensive help material that will display info about every database object you want and the relationships between these objects. And, if one has the good sense to provide a description for objects during creation, xSQL Documenter will display that description, making it that much easier to understand the role and function of the object. If this documentation is not to be uploaded in an intranet to be viewed using a browser you can use the .chm file which is indexed and searchable. This makes finding information about a particular object even easier.

This tutorial shows only the tip of the iceberg regarding the capabilities and the information that xSQL Documenter is able to display. For a full reference to this capabilities you can view xSQL Documenter's online help.

Thursday, January 5, 2017

Simplifying database deployment

In every discussion I have about the deployment process with other developers or project managers, the same sentence is said over and over again:

Every software development team must have an automated deployment process.
The benefits of automation are obvious to almost everyone, but, for those that are not familiar with the process, they can be summarized to the following statements:

  1. Deployment becomes less error-prone.
  2. No special knowledge is required to perform the deployment because this knowledge is embedded into the system.
  3. Developers can focus on writing code and developing new awesome features
  4. Adding new deployment targets is very simple
  5. Frequent uploads / releases.
However, if you look at the actual number of teams that have actually automated deployment, you'd be surprised by how small it really is. If deployment automation is such an indisputable necessity, how come most development teams shy away from it? The reason is that, at first sight, it seems like the overhead of setting up and configuring the process is too big to justify the potential benefits. While I don't personally agree with this, I find it very hard to convince teams to automate their deployment simply by explaining the benefits or telling them that the overhead is really not that big. So, in this article I've opted for a slightly different approach. Rather than making an argument in favor of switching to a fully automated deployment right away, I think that simplifying / automating only some parts of the deployment process, makes for a smoother and easier transition.

Let's have a look at how one would simplify the database deployment in this process. Suppose you have a web based transaction processing system that is used by multiple companies. Each company would have its own database on their server so every time the database structure is changed, a change script needs to be run on each database to synchronize their schemas. If there are just one or two databases, doing this manually is not really a problem. But when that number starts to grow, this task becomes very tedious and it's quite possible that the person in charge of the task will make a mistake. Thankfully, there are many tools that greatly simplify this process and one that I personally like to use is xSQL Script Executor. It allows you to build script packages that you can execute in any number of servers / databases. Lets see how this is done. I'm using SQL Server databases in this example, however, the process is exactly the same with the other databases engines supported by Script Executor which are MySQL, DB2 and SQL Server Compact. The only difference is the way the connection is specified.

The first thing to do is to create a new project in which you add a database group (right click on the panel and then click "Add database group"). In this group, I will add all the databases that will be used by right-clicking on the group name and clicking "Add database" which will show the dialog below.

I'll be using the NORTHWIND database in this demo so I named the database group Northwind. Then, I proceeded to add all the databases on which I will be executing the script. Here is the structure of the database group:


All of these databases are currently empty. I used xSQL Schema Compare to compare the NORTHWIND database with one of the empty databases, in order to generate the change script for the empty databases, which will be saved in a .sql file. Next, this file will be added to the 'Scripts' panel in Script Executor. Every script needs to reside in a container so first I created a Script Container named 'NorthwindScripts' by right-clicking on the Scripts panel and choosing Create a new container from the menu. This is where I added the script file generated by Schema Compare as shown in the picture below:


All that is left now is to configure the package mappings and then we're all set to run the script. This is done by clicking Package > Configure. This is where you specify which scripts will be run on each Database group. Since there is only one Database group and one Script container they will automatically be mapped together, however you can easily modify the mappings in cases when there are multiple Database groups and Script containers (refer to the online help). The package configuration looks like this. 



Before I execute the scripts on the Northwind database group, note that you can further customize which scripts are executed on the databases in a database group by checking / unchecking the check boxes in the panel to the right. Then, by clicking the 'Execute' button, all the checked scripts are executed on the databases to create the Northwind database objects on the empty databases I created earlier. As you can see from the screen shot below, the Northwind database's objects are created on the Northwind database on SQLServer2016 which was one of the Servers added to Script Executor.


The last thing that I want to cover in this article is how you can automate the entire database deployment process by using the command line versions of xSQL Schema Compare and Script Executor. Here is what you would do:
  1. Generate an XML file that has the configurations for a schema comparison between the development database and one of the live databases. Instead of the synchronization, specify an option on the XML to have the change script saved in a .sql file. Keep in mind to add the Synchronize="false" attribute so that Schema Compare Command Line won't excecute the script (this will be done by Script Executor). Here is how that XML file would look:
    <?xml version="1.0" encoding="utf-8" ?>
    <CommandLineParameters xmlns="http://www.xsql.com/sqlschemacmd.xsd">
      <LeftDatabase>
        <SqlServer>(local)</SqlServer>
        <DatabaseName>Left_DB</DatabaseName>
        <TrustedConnection>true</TrustedConnection>
      </LeftDatabase>
      <RightDatabase>
        <SqlServer>(local)</SqlServer>
        <DatabaseName>Right_DB</DatabaseName>
        <TrustedConnection>true</TrustedConnection>
      </RightDatabase>
      <CommandLineSettings>
        <SchemaScriptFile>[PathToSQLFile]</SchemaScriptFile>
        <SchemaLogFile>log.txt</SchemaLogFile>
        <SchemaWarningsFile>warnings.txt</SchemaWarningsFile>
        <ErrorLogName>error.txt</ErrorLogName>
        <CompareSchema Direction="RightAsLeft" Synchronize="false"></CompareSchema>
      </CommandLineSettings>
    </CommandLineParameters>
    
  2. Then, create a project in the Script Executor Interface (as explained in this article), where you add all the databases that you want to be updated and the script file whose path you specified on the XML file as in the example above (if the file does not exist, just create an empty .sql file). Here is how the batch file would look:
    "C:\Program Files (x86)\xSQL Software\SQL Server Comparison Bundle v9\xSQLSchemaCmd.exe" PathToXMLFile
    "C:\Program Files (x86)\xSQL Software\Script Executor\ExecCmd.exe" /p:PathToProjectFile
    

Simply by executing these two commands you can transfer any changes from the development schema to any number of live databases you wish.

So there you have it, with xSQL Script Executor and just a few simple steps you can greatly simplify and automate a quite tedious part of the deployment process.

Wednesday, January 4, 2017

xSQL Documenter now supports SQL Server 2016 and SQL Azure

The best database documenting tool in the market, xSQL Documenter, just got better! The new version 5 released today now supports SQL Server 2014, SQL Server 2016 and SQL Azure.

When you reach the download page you will notice that there are 5 different packages - we left the "2008" package selected by default but please choose the correct package based on the version of the SQL Server client tools you have installed on your machine. The xSQL Documenter relies on the SMO api and since the SMO is updated with every version of SQL Server we provide a different package for each version. Note however that the SMO is backwards compatible, so if for example you have the SQL 2016 client tools installed, you only need the 2016 version of the xSQL Documenter and you can document all the earlier versions of SQL Server.
Today only, you can get a 15% discount on a new xSQL Documenter license. Use code DOCV5NEW on checkout.

Download your free trial now and see for yourself why xSQL Documenter is the best!

Tuesday, January 3, 2017

How to push database schema changes to hosts you cannot connect to

In most cases when you need to push database schema changes from your dev environment to QA/staging or from QA to production you are able to connect to both environments, the source and the target, at the same time in which case a tool like xSQL Schema Compare makes pushing the changes from the source to the target very easy and straightforward.
However, if you do not have access to the target database then pushing the changes becomes a bit of a challenge. Imagine for example that you have to upgrade a client’s database. To complicate things further imagine having tens or hundreds of clients running your software with a SQL Server back-end and to make matters worse your clients are running different versions of the software / database. In the past (I think there are still software publishers doing that) you would likely send your clients a set of scripts with detailed instructions telling them which scripts to run in what order based on whatever version they were upgrading from. If you have experience with that process you know it’s painful for both the software publisher and the client. In the case of small clients they would often have to hire outside help to perform the upgrade based on your instructions as the client lacks the in-house expertise so the process for them becomes not just painful but expensive too.

This is exactly what we build xSQL Builder for, to allow you to make the pushing of the schema changes to your clients’ environments easy and painless. A very simple and intuitive wizard guides you in creating a self-contained executable package in just minutes. You can then send the executable to your clients and all they would need to do is run it.

The executable package contains a snapshot of the master or source database schema that you wish to push to your clients. When executed it compares that schema snapshot to the target database on the client’s environment and performs the necessary schema changes on the target to make it the same as the source. The fact that your clients may have different versions of the database does not matter, the same executable package will upgrade any previous version to the current version you are pushing.

There are a few other convenient features like specifying pre and post synchronization scripts you may wish to run on a target and customizing the comparison and synchronization process based on your needs.

What makes this even better is that the distribution of the run-time library that makes this possible is royalty free. In other words you only need a single license for yourself and you can send those "magic" executable packages to as many clients as you need to.

xSQL Builder supports SQL Server versions from SQL Server 2005 and up, including SQL Server 2016 and SQL Azure.

Download and try the xSQL Builder now and if you decide to buy before the end of January 2017 ask us for a special discount.

Wednesday, December 28, 2016

Failed to map database objects. An item with the same key has already been added.

We just released a new build (9.0.5.0) of xSQL Schema Compare tool that addresses a recently reported issue with object mapping. In certain cases the database schema comparison may fail in it's first stage (object mapping) with the error message "Failed to map database objects. An item with the same key has already been added." 
If you run into this issue please download and install the latest build from our website: http://www.xsql.com/download/sql_server_comparison_bundle/

Friday, December 16, 2016

Synchronization tools for SQL Server Express

Most of the tutorials/case studies I have presented in this blog have had SQL Server Enterprise edition as their primary focus. However, the reality is that, this version, if you didn't get the hint from its name, is mostly for big enterprises that need advanced features like SQL Server Agent or Analysis Services. In any other case this version is a bit of an overkill. In these cases, SQL Server Express is a very good starting point because it's free and offers a lot to work with, such as a full database engine, full T-SQL support, full text search, native XML, and some very useful built in tools like SQL Server Management Studio. A few classic examples where SQL Server Express is a very good option are:

  • Deploying desktop windows solutions that use SQL Server to users who do not own a SQL Server. Given that it's free, its setup can be embedded in the application's setup so that Windows application can enjoy most of SQL Server's functionality.
  • Lightweight web applications that only need to use small SQL Server databases such as websites using a CMS like Umbraco.
  • Testing and developing applications with a local database.
Although it has some limitations regarding the processing power it can use, computer memory available and database size, it is suitable for a wide range of applications. Now, this might be something that one does not think of right away, but at some point in time, it's certain that there will be the need to perform some kind of database synchronization.This is where SQL Server Express has another advantage. Some of the synchronization tools, xSQL Schema Compare and xSQL Data Compare included, follow the same 'no charge' pattern set by Microsoft for this version of SQL Server. The Lite version of these two tools, when used with SQL Server Express offers the full functionality of the licensed version. Let's first have a look at the windows desktop solution case which, in my opinion is a very interesting case where schema synchronization is useful.

Suppose you have created and deployed a desktop Windows application that uses a SQL Server database. A good example here might be an app that does some sort of system monitoring and stores any data it finds in the database. SQL Server Express is a clear choice for the database because there is no complex functionality required and the database size is very likely to be small. Let's also suppose that you have just developed a major update for the app that includes a lot of database changes. How would you go about transferring those changes in the clients' databases? One option would be to generate the full schema script from SSMS and during the update's installation on the client, run that script to recreate the database. As you can imagine this is not an optimal choice because it would delete all the data that are already saved in the database. Another option is to manually generate the script but, in most cases, simply mentioning this, would get you a few "are you kidding?" looks as it is a very tedious and error prone process. Buying a comparison tool seems like a big waste of money if you're going to use it just for this one thing, so here is where the Lite version of xSQL Schema Compare comes to the rescue. For absolutely no cost you get a tool that, on SQL Server Express, will compare the 2 database versions and generate a synchronization script that can be run during the installation process and perform all the necessary changes in the client database.

A scenario in which data comparison on SQL Server Express might be necessary is the development of websites with a CMS. Content Management Systems store all the content management-related data in a database. Take Umbraco for example. It uses an element called Document Type to provide the structure of different webpages. This element stores all the info it needs in a database which can very well be a SQL Server Express database as this type provides the necessary functionality and more. It's always a good idea to develop these sites locally or in a development server and once the changes are fully tested, upload those on the live server. Of course along side this upload, the data on the database need to be transferred as well so that the site admin won't have to recreate the new content structures. Backing up and restoring the database is not a good idea because there are some data (like the actual content of the site) that do not need to be transferred, and if the live site is on a Cloud service like Azure, restoring is not possible. Again, the best option here would be a synchronization tool and a very good choice is xSQL Data Compare. Since the synchronization will be performed on SQL Server Express, the FREE Lite version of xSQL Data Compare can be used to transfer the data. Also, the synchronization process is highly customizable (refer to the online help), so you can manually determine which tables and what data in those tables you want to synchronize. This way, only the data regarding the content structure will be transferred.
In conclusion, I think it's safe to say that the two scenarios mentioned here are a very small portion of the huge number of cases where the application of SQL Server Express is enough to fulfill a software's database needs. Keeping in mind that database synchronization is a process that sooner or later will take place in most of these cases, the extension of the 0 cost principle of SQL Server Express to its synchronization tools like in the case of the Lite versions of xSQL Data Compare and Schema Compare is something that can greatly reduce the development and maintenance costs of software.


   

Monday, December 12, 2016

Database synchronization in the Software Development Life Cycle

Reading the title, most of you are probably thinking: What does database synchronization have to do with the Software Development Life Cycle (SDLC)? Stick around, because I'll get to that in just a minute. First, let me give a quick introduction to SDLC for those one or two developers out there who, by an impossible twist of fate, may have never heard of SDLC in their working experience. SDLC is a multi-phase process which ensures that good software is supplied to the customers. The term 'good software' has quite a broad definition but generally, 'good software' implies software that meets the requirements, has been tested thoroughly and has minimal errors. SDLC has a number of variations, but usually the software will go through these 5 stages:

  1. Requirement analysis 
  2. Design
  3. Implementation / Development
  4. Testing
  5. Maintenance
Since, the focus of this article is database synchronization, I'll skip the first three stages and go straight to the stages which deal with database synchronization, which are testing and maintenance.

In the context of testing, database synchronization is useful in preparing the testing environment. For example, usually when a web application or a new feature is completed it will first be published on a test domain which is made available only to some chosen individuals / groups. This test site will probably need its own database that will have to be created or updated every time a change is made. You could backup the development database and restore it in the test environment or generate the database's script and execute it on the test environment but this would require the database to be recreated every time which can be a very time consuming process for large databases. Also, this is not possible if the databases are in the Azure cloud environment. The best option here is to use a synchronization tool like xSQL Schema Compare or xSQL Data Compare. So, you could use xSQL Schema Compare to transfer any schema changes from the development database to the testing environment and xSQL Data Compare to transfer any changes in lookup data. As a side benefit, xSQL Schema Compare can also be used to take periodic snapshots of the database in order to keep track of the changes made to it and rollback any of them is necessary.

Since the synchronization process is fairly straightforward and more or less the same in most of the scenarios, I'll first explain the other scenario in which database synchronization is necessary and then demonstrate how it's done and how to automate it.

The other, very important stage where database synchronization might take place in, is maintenance. In this stage, this process is done in both directions. First of all, for every bug fix or new feature, schema changes and lookup data are transferred from the development environment to the testing and then the live one. This process is the same as the one in the testing stage. Secondly, to make sure that the software is working correctly, quality assurance is performed. Quality assurance can have its own environment or it can use the testing environment. One thing is for certain though, it needs to have data that is as close as possible to the live data. Obviously, no type of data satisfies this condition better than the live data itself. By using xSQL Data Compare, these live data can be transferred to the quality assurance environment where they can then be used as needed.
Without further ado, let's proceed to a demonstration of schema and data synchronization. I'll be using the AdventureWorks2012 database in this demo. I made a copy of this database (AdventureWorksCopy) which will be used as the testing environment's database. Suppose this database belongs to a company that has decided to extend its medical and dental benefits to the employee families. Obviously, they will want to have some data in the system for the employee's family members. To do this, a table called EmployeeDependant is added to the HumanResources schema in the development database which has records for the employee's families. Of course, before this feature can be published it needs to be tested, which means that the schema changes need to be transferred to AdventureWorksCopy. There are 4 very simple steps to this process.

  1. Add the databases in xSQL Schema Compare.
  2. Compare AdventureWorks2012 with AdventureWorksCopy. The comparison reveals that there is a table EmployeeDependant in AdventureWorks2012 that does not exist in AdventureWorksCopy (note the one-way arrow to the right).
  3. Generate the synchronization script.
  4. Execute the script. By opening the database in SSMS I can see that the EmployeeDependant table is added to the AdventureWorksCopy database.

The new EmployeeDependant table has a column named 'RelationshipWithEmployee'. Instead of it being a simple VARCHAR column it's better to have it as a foreign key to a 'Relationships' table. The records in this table will probably never change (there is a fixed number of relationship types in a family), so it can be used as an example of the lookup data that may need to be transferred from the development environment to the testing one. Doing this synchronization with xSQL Data Compare is, again, a very straightforward process. Before I show this process' steps, here is a screen shot of the data in the Relationships table that will be transferred to the AdventureWorksCopy database:

To add these data to the Relationships table in AdventureWorksCopy database do the following:

  1. Add the databases to xSQL Data Compare.
  2. Choose the objects that need to be compared. In this case, only the Relationships table will be synchronized, so only that table will be selected from the objects to be compared.
  3. Compare the tables
  4. Generate the synchronization script for the AdventureWorksCopy database, Here is the script that is generated:
    SET XACT_ABORT ON;
    SET ARITHABORT ON;
    SET NUMERIC_ROUNDABORT OFF;
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
    
    
    BEGIN TRANSACTION;
    
    
    /*-- -Insert(s): [HumanResources].[Relationships] */
    SET IDENTITY_INSERT [HumanResources].[Relationships] ON;
    INSERT INTO [HumanResources].[Relationships] ([Id],[RelationshipName]) VALUES(1,'Spouse');
    INSERT INTO [HumanResources].[Relationships] ([Id],[RelationshipName]) VALUES(2,'Sibling');
    INSERT INTO [HumanResources].[Relationships] ([Id],[RelationshipName]) VALUES(3,'Parent');
    INSERT INTO [HumanResources].[Relationships] ([Id],[RelationshipName]) VALUES(4,'Child');
    SET IDENTITY_INSERT [HumanResources].[Relationships] OFF;
    
    
    
    COMMIT TRANSACTION;
    
  5. Excecute the script. After execution, if a select query is run on the Relationships table AdventureWorksCopy database, it will display the following data: 


Using a similar process to the one in this demo you can copy the data in the live database in the Quality Assurance database and run any tests that you need.

In most cases, these tasks are repetitive. For example, an organization might have the practice of synchronizing the live data with quality assurance every 3 days. Instead of doing this manually every time, you can just generate a XML configuration file for xSQL Data Compare Command Line by clicking the button in the picture below and then, using Windows Scheduler, schedule the comparison to be run periodically with that XML file as an argument.
Automation of the schema comparison is exactly the same as automation of data comparison. The only difference is that xSQL Schema Compare Command Line needs to be used.

In conclusion, the benefits of using synchronization tools like xSQL Schema and Data compare are quite obvious. They can simplify and automate parts of the SDLC that are trivial and boring and would otherwise, take a relatively long time to complete.

Tuesday, November 29, 2016

Big savings every hour, today only

Today only, Nov 30, 2016, from 10am until midnight US Eastern Time, you can get a new Silver Subscription at significant savings (one month subscription not included). The amount you save changes from one hour to the next. Here are the promo codes for each hour:
  • from 10am to 10:59am -> ELASTIC10
  • from 11am to 10:59am -> ELASTIC11
  • from 12pm to 10:59am -> ELASTIC12
  • from 1pm to 1:59pm -> ELASTIC13
  • from 2pm to 2:59pm -> ELASTIC14
  • from 3pm to 3:59pm -> ELASTIC15
  • from 4pm to 4:59pm -> ELASTIC16
  • from 5pm to 5:59pm -> ELASTIC17
  • from 6pm to 6:59pm -> ELASTIC18
  • from 7pm to 7:59pm -> ELASTIC19
  • from 8pm to 8:59pm -> ELASTIC20
  • from 9pm to 9:59pm -> ELASTIC21
  • from 10pm to 10:59pm -> ELASTIC22
  • from 11pm to 11:59pm -> ELASTIC23
There's no particular pattern, the savings for each hour are random so if the price looks right to you don't wait. IMPORTANT: The discount applies to new subscriptions only. The 1 month subscription is not included.