Well, a timestamp is defined as the integer number of seconds from 1st of January 1970, but not 1st January 1970 itself, that would mean 0 seconds and that is reserved as the 'zero time'.
So, converting is easy in T-Sql (Microsoft Sql Server): @dateTime=DateAdd(second,{d '1970-01-01'},@timeStamp) @timeStamp=DateDiff(second,{d '1970-01-01'},@dateTime)
In order to debug SQL many people open new windows in Query Analyser or Management Studio trying to see where the errors come from and opening transactions and rolling them back and basically be miserable.
Yet, even from Microsoft SQL 2000 stored procedures had debug support. You would use Query Analyser, open Object Browser, right click a stored procedure and select Debug.
However, in SQL 2005 you can't do that anymore. Query Analyser is no longer available, the Management Studio doesn't have debug options and the SQL 2000 Query Analyser doesn't allow you to debug stored procedures on SQL 2005 servers. But there is support for SQL debugging in Visual Studio .NET, in the Professional and Team versions. Let me rephrase: If you have the Express or Standard editions you are out of luck. No SQL 2005 debugging for you. I did some queries on the web searching for third party sql debuggers, maybe something from Microsoft, like their Javascript Debugger (which works better than the in-built javascript debugging in Visual Studio, btw)
Well, you can! But you need to use the sp_OA* stored procedures and VBScript. Here is a link to the user defined function that allows you to regex in sql: Regular Expressions in T-SQL
You may get this error while trying to use the OLE Automation : Msg 15281, Level 16, State 1, Line 1 SQL Server blocked access to procedure 'sys.sp_OACreate' of component 'Ole Automation Procedures' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Ole Automation Procedures' by using sp_configure. For more information about enabling 'Ole Automation Procedures', see "Surface Area Configuration" in SQL Server Books Online.
The solution I've found is use sp_configure to enable Ole Automation Procedures like this:
EXEC sp_configure 'show advanced options', 1 -- make them available reconfigure
EXEC sp_configure 'Ole Automation Procedures', 1 -- turn on OLE reconfigure
EXEC sp_configure -- to see the new value EXEC sp_configure 'show advanced options', 0 -- make them unavailable reconfigure
In MS Sql when you try to insert or update a field value or parameter that is bigger than the defined size you get String or binary data would be truncated and the query fails. In order to get rid of this, you can use SET ANSI_WARNINGS OFF. But, warning (not ANSI :) ), there are some drawbacks that you have to be aware of before using SET ANSI_WARNINGS OFF :
putting SET ANSI_WARNINGS OFF in a stored procedure will force a procedure recompilation each time, so it is better to set it before the execution of the stored procedure
this setting will disable the indexes, so queries might run slower
no error will be generated when a division by zero appears and a null value is returned (this might not sound as a drawback, but think that you don't always want to return null in some cases and you want at least to be aware of them)
What SET ANSI_WARNING does: - disables the warning message from aggregated functions when finding null values - returns null on divisions by zero and arithmetic overflows - values are truncated when the length of the data is bigger than the defined size
Update October 6 2014: New stuff, compare Levenstein vs Sift here:
Algorithm: Levenstein Sift
String 1: String 2:
Result:
Update June 25th 2013: I've decided to play a little with the suggestions in the comments and check for validity. This was spurned by the realization that a lot of people use my algorithm. So, in order to celebrate this, here is the "3B" version of the Sift3 algorithm: It is made in Javascript, this time, as it was easier to test and has the following extra features:
a maxDistance value that tells the algorithm to stop if the strings are already too different.
two pointers c1 and c2, rather than a single pointer c and two offsets
Instead of dividing to 2 the total length of the strings compared, now I divide it with 1.5. Why? Because this way the value is closer to the Levenshtein distance computed per random strings
Happy usage! The variant I posted was totally buggy. I removed it. Just use sift3Distance.
A while ago I wrote an entry here about Sift2, an improvement of Sift, the original and silly string distance algorithm. Now I am publishing Sift3, which is way more accurate and even simpler as an algorithm.
I found out that my algorithm is part of a class of algorithms that solve the Longest Common Substring problem, therefore I calculated the LCS, not the distance, then the distance from the LCS. The result is way more robust, easy to understand and closer to the Levenshtein algorithm both on random strings and user databases. Not to mention that there is no goto in this one.
BTW, if you are looking for an algorithm that detects switched words, this is not it :) This just looks for typos and small regional differences between the strings. I mean, you could normalize the strings, so that words are ordered by some mechanism, then it would work because the words wouldn't be switched :)
I promise to work on a word switching algorithm, but not in the near future. Without further ado, here is the code:
The C# code is a method in an object that has a private member maxOffset. As in Sift2 maxOffset should be around 5 and it represents the range in which to try to find a missing character.
publicfloat Distance(string s1, string s2, int maxOffset) { if (String.IsNullOrEmpty(s1)) { return String.IsNullOrEmpty(s2) ? 0 : s2.Length; } if (String.IsNullOrEmpty(s2)) { return s1.Length; } int c = 0; int offset1 = 0; int offset2 = 0; int lcs = 0; while ((c + offset1 < s1.Length) && (c + offset2 < s2.Length)) { if (s1[c + offset1] == s2[c + offset2]) lcs++; else { offset1 = 0; offset2 = 0; for (int i = 0; i < maxOffset; i++) { if ((c + i < s1.Length) && (s1[c + i] == s2[c])) { offset1 = i; break; } if ((c + i < s2.Length) && (s1[c] == s2[c + i])) { offset2 = i; break; } } } c++; } return (s1.Length + s2.Length)/2 - lcs; }
And here is the T-Sql code. This version is actually an improvement of my original source, gracefully provided by Todd Wolf:
CREATEFUNCTION [DBO].[Sift3distance2] ( @s1 NVARCHAR(3999),@s2 NVARCHAR(3999),@maxOffset INT ) RETURNSFLOAT AS BEGIN DECLARE @s1LEN INT,@s2LEN INT
IF(@s1Pos>0 AND (@s1Dist<=@s2Dist OR @s2Pos<1) AND @s1Dist<@maxOffset) SET @s1Offset=(@s1Pos-@wrkPos)+1 ELSE IF(@s2Pos>0 AND (@s2Dist<@s1Dist OR @s1Pos<1) AND @s2Dist<@maxOffset) SET @s2Offset=(@s2Pos-@wrkPos)+1 END
SET @currPos=@currPos+1 END
RETURN(@s1LEN+@s2LEN)/2.0-@matchCnt END
It doesn't give the same exact results as my own code, yet the result is close enough and the speed is about 20% higher.
You sometimes need to copy the exact structure of a database to an Sql2000 server, even if the source server is 2005.
Follow these steps:
open 2005 Sql Server Management Studio
right click on the offending database and go to Tasks -> Generate Scripts
do NOT check Script all objects in the selected database
click Next
set Include if NOT EXISTS to False
set Script for Server Version to SQL Server 2000
try to check only the objects and types of objects you actually need
create the script
delete all occurences of "WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)" from the generated script
Now the script should work on an SQL 2000 Server.. For the copying of data, the Server Management Studio has an option called Copy DatabaseExport Data, also in Tasks, that now accepts an Sql 2000 Server as destination.
In other words: those curly bracket things in SQL. What? curly brackets in SQL? Yes! Imagine that :)
The idea is that most database systems adhere to the ODBC standard, at least ODBC 1.0. That means that, when you communicated with a database, you can send so called ODBC escape sequences that are translated into the SQL engine native objects.
Quick example: SELECT {d '2007-03-15'} will work in all ODBC 1.0 compliant DBMSs, including Microsoft SQL Server, MySql, PostgreSQL, Oracle, etc. and select a date object from 15 of March 2007, no matter the server configured country or language.
Interested yet? You can read the ODBC Programmer's Reference for more details. Short story shorter, here are the working and interesting parts (to me) of the ODBC escape sequences: select {d '2007-02-13' } select {t '22:20:30' } select {ts '2007-02-13 22:20:30' } select {fn curdate()} select {fn curtime()} select {fn User()} select {fn Database()} select {fn week(getdate())} select {fn quarter(getdate())} select {fn monthname(getdate())} select {fn dayname(getdate())} select {fn curdate()} select {fn dayofweek(getdate())} select {fn dayofyear(getdate())} select {guid '12345678-1234-1234-1234-123456789012'}
Update!! Read the Sift3 post. It is an even better algorithm.
A while ago I wrote a little algorithm that tried to cope with the large amount of time that the Levenshtein edit-distance algorithm took to compare two strings. It was a really funny algorithm, but it was fast enough to show me the similarity between strings that, after all, should have been either very similar or different.
Meanwhile I started thinking if I could improve on it. I was sure I could, because it wasn't very scientific, it was empirical. And finally I did it. This is the Sift2 algorithm, along with an SQL server function that can make one million string comparisons in 2.5 minutes. Compared with Levenshtein, Sift2 performs 10 to 25 times faster and it is four times faster than Sift.
The concept:
Starting from the beginning of both words, compare the letters on the same position.
If the same, move forward, else search the letter from the first word in the next maxOffset letters in the second word and viceversa.
Offset the words according to the closest found letter, add 1 to distance
Repeat until one of the words ends
Add to the calculated distance half of the length of string remained unparsed from the other word
That's it! Here is the code:
You can find a nice OOP Javascript implementation at IT BASE.
Performance: The algorithm seems to be working fine for letter insertions, typos, letter inversions and such. It gives slightly different values than Levenshtein when big words are inverted. When a lot of letters are inverted, the difference from Levenshtein increases. Example: abcdefghijkl vs. badcfehgjilk (every two letters inverted) results in 0.42 similarity in Levenshtein and 0.08 in Sift2. But let's face it, the two words are really different.
Update: I've optimised the algorithm a little and also changed the formula so that it matches the Levenshtein distance as close as possible. The basic idea remains the same, but now the average error from Levenshtein (calculated or real company name and address data) is only 3%. Some people saw the goto line and immediately laughed. Well, I tried replacing it with a break and a subtraction and even removed the subtraction altogether (thus maiming the algorithm) and the goto implementation was still the fastest. So I will continue to use goto, as it is more efficient.
Request: I have seen a lot of people actually searched on Google and got here. I would really really really like some comments, links to implementations or whatever... It's my baby after all. Thanks!
As far as I understand, the old declarative ADO.NET Begin/RollBack/CommitTransaction model has become obsolete and a new TransactionScope model is used in NET 2.0. You have to add the System.Transactions.dll file to your references.
Basically, the C# code is like this:
using (TransactionScope scope=new TransactionScope (scopeOption,transactionOptions,interopOption)) { // do database ops
// if everything is alright scope.Complete(); }
scopeOption is an enum of type TransactionScopeOption, with the options Required (requires a transaction and uses if there is already on open), RequiresNew (always opens a new transaction), Suppress (don't use a transaction, even if one is open)
transactionOptions is of type TransactionOptions which has two interesting properties: IsolationLevel and Timeout.
interopOption is an enum of type EnterpriseServicesInteropOption and specifies how distributed transactions interact with COM+ transactions.
But what about the old NET1.1 framework? Doesn't it have something like that? Here comes Alexander Shirshov with help: TransactionScope in .NET 1.1
This is a nice and simple article about accessing data from a lot of datarows. While using the string index will make the code more readable, using the integer index will make the code faster. The solution? Get the numeric indexes at the beginning of the loop, based on string indexes. Assert the indexes exist for better debugging. Very elegant. Also, check out the user comments, which are pretty good and to the point.
Code example:
int customerIDIndex = table.Columns.IndexOf("customerID"); int customerFirstNameIndex = table.Columns.IndexOf("firstName"); int customerLastNameIndex = table.Columns.IndexOf("lastName");
System.Diagnostics.Debug.Assert(customerIDIndex > -1, "Database out of sync"); System.Diagnostics.Debug.Assert(customerFirstNameIndex > -1, "Database out of sync"); System.Diagnostics.Debug.Assert(customerLastNameIndex > -1, "Database out of sync");
foreach(DataRow row in table.Rows){ customer = new Customer(); customer.ID = (Int32)row[customerIDIndex]; customer.FirstName = row[customerFirstNameIndex].ToString(); customer.LastName = row[customerLastNameIndex].ToString(); }//end foreach
Using SQL Server instead of Access files: 1. Run aspnet_regsql.exe (from the NET Framework 2.0 folder) 2. Add to web.config (inside the configuration tag): <connectionStrings> <remove name="LocalSqlServer"/> <add name="LocalSqlServer" connectionString="Data Source=localhost;Initial Catalog=aspnetdb;Integrated Security=True" providerName="System.Data.SqlClient"/> </connectionStrings> (that's because LocalSqlServer is already defined by default. Really dumb) 3. Go to the Website menu in Visual Studio -> ASP.NET Configuration and create users, roles and access rules.
Logging out programatically: FormsAuthentication.SignOut();