SQLsharp Manual
SQLsharp Manual
Copyright © 2006 - 2017 Sql Quantum Lift, LLC. All rights reserved.
www.SQLsharp.com
i
Table of Contents
TABLE OF CONTENTS I
GENERAL INFORMATION 1
Copyrights 1
Introduction 4
Requirements 4
Contact Information 4
Installation / Setup 5
Updating 5
Internally (not available in Free version) 5
Externally 6
Strings 18
String_CompareSplitValues (Not available in Free version) 19
String_Contains 19
String_Count 20
String_Cut 20
String_DamerauLevenshteinDistance (Not available in Free version) 21
String_DamerauLevenshteinDistancePlus (Not available in Free version) 21
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
ii
String_EndsWith 22
String_Equals 23
String_FixedWidthIndex (Not available in Free version) 23
String_FixedWidthSplit (Not available in Free version) 24
String_IndexOf 24
String_InitCap 25
String_IsNumeric 25
String_Join 27
String_LastIndexOf 27
String_LevenshteinDistance (Not available in Free version) 28
String_LevenshteinDistancePlus (Not available in Free version) 28
String_Newline 29
String_NthIndexOf 30
String_PadBoth (Not available in Free version) 30
String_PadLeft 31
String_PadRight 31
String_Replace 31
String_Split 32
String_Split4k 33
String_SplitIntoFields (deprecated) 33
String_SplitResultIntoFields (Not available in Free version) 33
String_SplitKeyValuePairs (Not available in Free version) 34
String_StartsWith 35
String_Trim 36
String_TrimChars (Not available in Free version) 36
String_TrimEnd (Not available in Free version) 36
String_TrimStart (Not available in Free version) 36
String_TryParseToInt 37
String_WordWrap 37
Math 39
Math_BitwiseLeftShift 39
Math_BitwiseRightShift 39
Math_CompoundAmortizationSchedule 39
Math_Constant 40
Math_Convert 41
Math_Cosh 42
Math_CubeRoot 42
Math_Factorial 43
Math_FormatDecimal 43
Math_FormatFloat (Not available in Free version) 43
Math_FormatInteger (Not available in Free version) 44
Math_IEEERemainder (Not available in Free version) 44
Math_IsPrime 45
Math_NthRoot (Not available in Free version) 45
Math_RandomRange 45
Math_Sinh 47
Math_Tanh 47
Math_Truncate 47
Network 48
INET_AddressToNumber 48
INET_DownloadFile (Not available in Free version) 48
INET_FTPDo (Not available in Free version) 49
INET_FTPGet (Not available in Free version) 49
INET_FTPGetBinary (Not available in Free version) 50
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
iii
Miscellaneous 62
Util_CRC32 62
Util_Deflate 62
Util_GarbageCollect (Not available in Free version) 62
Util_GenerateDateTimeRange 63
Util_GenerateDateTimes 63
Util_GenerateFloatRange 63
Util_GenerateFloats 64
Util_GenerateIntRange 64
Util_GenerateInts 65
Util_GetTotalMemory 65
Util_GUnzip 65
Util_GZip 65
Util_Hash 66
Util_HashBinary 66
Util_Inflate 67
Util_IsValidCC 67
Util_IsValidCheckRoutingNumber 68
Util_IsValidConvert 68
Util_IsValidPostalCode 69
Util_IsValidSSN 69
Util_Print 70
Util_ToWords 71
Date 72
Date_Age 72
Date_BusinessDays 72
Date_BusinessDaysAdd (not available in Free version) 74
Date_DaysInMonth 75
Date_DaysInMonthFromDateTime 75
Date_DaysLeftInMonth (Not available in Free version) 75
Date_DaysLeftInYear 76
Date_Extract 76
Date_Format 77
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
iv
Date_FormatTimeSpan 78
Date_FirstDayOfMonth 79
Date_FromUNIXTime 80
Date_FullDateString 80
Date_FullDateTimeString (not available in Free version) 80
Date_FullTimeString 81
Date_GetDateTimeFromIntVals 81
Date_GetIntDate 82
Date_GetIntTime 82
Date_IsBusinessDay 82
Date_IsDaylightSavingTime 82
Date_IsLeapYear 83
Date_LastDayOfMonth 83
Date_NewDateTime 84
Date_NthOccurrenceOfWeekday 84
Date_ToLocalTime (Not available in Free version) 84
Date_ToUniversalTime (Not available in Free version) 85
Date_ToUNIXTime 85
Date_Truncate 85
Internal 87
SQLsharp_Download (Not available in Free version) 87
SQLsharp_GrantPermissions 87
SQLsharp_Help 87
SQLsharp_IsUpdateAvailable 87
SQLsharp_SetSecurity 88
SQLsharp_Setup 88
SQLsharp_Uninstall 88
SQLsharp_Version 89
SQLsharp_WebSite 89
File_Move 101
File_MoveMultiple 102
File_PathExists 102
File_SplitIntoFields 103
File_Touch 104
File_WriteFile 104
File_WriteFileBinary 105
Database 107
DB_BulkCopy 107
DB_BulkExport (Not available in Free version) 109
DB_CreateOrAlterQueryInfoTables (Not available in Free version) 111
DB_CurrentSQLStatement (Not available in Free version) 113
DB_DescribeResultSets (Not available in Free version) 113
DB_DeserializeResults (Not available in Free version) 115
DB_DumpData (Not available in Free version) 117
DB_ForEach (Not available in Free version) 120
DB_GetQueryInfo (Not available in Free version) 122
DB_HTMLExport (Not available in Free version) 124
DB_NewID (Not available in Free version) 129
DB_SerializeResults (Not available in Free version) 129
DB_SerializeResultsInChunks (Not available in Free version) 130
DB_ThrowException (Not available in Free version) 131
DB_TryCatch (Not available in Free version) 132
Convert 137
Convert_BinaryToHexString 137
Convert_DateTimeToMSIntDate 137
Convert_FromBase64 137
Convert_HexStringToBinary 137
Convert_HtmlToXml 138
Convert_MSIntDateToDateTime 139
Convert_ROT13 139
Convert_ToBase64 139
Convert_UUDecode 140
Convert_UUEncode 140
LookUp 144
LookUp_GetCountryInfo 144
LookUp_GetStateInfo 144
Twitter 151
Twitter_BlockUser 151
Twitter_CreateFavorite 152
Twitter_DestroyDirectMessage 152
Twitter_DestroyFavorite 152
Twitter_DestroyStatus 152
Twitter_FollowUser 153
Twitter_GetBlocks 153
Twitter_GetFavorites 153
Twitter_GetFollowers 154
Twitter_GetFriends 154
Twitter_GetHomeTimeline 154
Twitter_GetMentions 155
Twitter_GetMessages 156
Twitter_GetMutes 156
Twitter_GetRetweetedBy 156
Twitter_GetRetweets 157
Twitter_GetRetweetsOfMe 157
Twitter_GetSentMessages 158
Twitter_GetStatus 158
Twitter_GetUser 158
Twitter_GetUserTimeline 159
Twitter_MuteUser 160
Twitter_Retweet 160
Twitter_SearchTweets (Not available in Free version) 161
Twitter_SendDirectMessage 161
Twitter_UnBlockUser 162
Twitter_UnFollowUser 162
Twitter_UnMuteUser 162
Twitter_Update 163
Twitter_xAuth 163
Type_FloatArray 176
Type_HashTable 180
Type_NVarcharArray 182
HISTORY 185
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 1 of 210
General Information
Copyrights
Copyright (c) 2006-2017 Sql Quantum Lift, LLC. All rights reserved.
The contents of the program (the SQL# program code), the Manual (this document), the Website
(www.SQLsharp.com), the logo, and the names “SQL#” and “SQLsharp”, in their entireties, unless otherwise
specified, are wholly owned by Sql Quantum Lift, LLC. No content at all from any of these sources may be
used in part or reproduced without the express written permission of Sql Quantum Lift, LLC. Installation of the
SQL# code into a database constitutes understanding of, and acceptance of, the End-User License
Agreement (EULA) as well as this copyright.
The full End-User License Agreement can be found in both the SQLsharp_EULA.htm file that came with
SQL#, as well as by executing the SQLsharp_DisplayEULA stored procedure after installing SQL#.
Twitterizer:
Copyright (c) 2008, Patrick "Ricky" Smith <[email protected]>. All rights reserved.
Copyright (c) 2011-2017 Sql Quantum Lift, LLC. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that
the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the
following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the Twitterizer nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 2 of 210
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as
under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in
section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce
its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative
works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in
section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed
patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the
software or derivative works of the contribution in the software.
SgmlReader:
Copyright (c) 2002 Microsoft Corporation. All rights reserved. (Chris Lovett)
Copyright (c) 2007-2008 MindTouch. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that
the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other materials provided with the distribution.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 3 of 210
3. The names of the authors may not be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY
CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
JsonFx:
The MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of
the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 4 of 210
Introduction
Welcome to SQL# (SQLsharp). SQL# is a .NET / CLR library that resides in a SQL Server 2005 (or
newer) database and provides a suite of User-Defined Functions, Stored Procedures, User-Defined
Aggregates, and User-Defined Types. This set of tools is designed to make the lives of countless SQL Server
professionals easier by providing the broad range of commands available in most other languages outside of
SQL (we will not speak of JCL or IBM’s horrendous Net.Data). The User-Defined Functions and Stored
Procedures are all prefixed with a “category” name much like the class names that you would find in C#, Java
/ J#, C++, VB.Net, etc. The names of the commands are in mixed case but SQL Server is not typically case-
sensitive so it will not matter if you use capitals or not (unless the Database you install SQL# into has a binary
or case-sensitive default Collation). Most of the functions will work in SAFE mode (this refers to security
setting of the SQL# Assemblies within Microsoft SQL Server). If you want to use the functions that access
anything outside of SQL Server (e.g. the Internet, the file system, the OS, etc), then you will have to change
the security setting of the SQL# Assembly that has the function(s) that you wish to use. The security setting
will need to be at least EXTERNAL_ACCESS or maybe even UNRESTRICTED (very few functions require
this security level). See details on SQLsharp_SetSecurity for more information on security levels.
Requirements
1) Microsoft SQL Server 2005 (with SP3) or newer
2) CLR Integration must be enabled (this will be done by the setup script if not done already)
Contact Information
Product Website: http://www.SQLsharp.com/
Problems to report / Questions: check the website at http://www.SQLsharp.com/faq/ or use the contact form
at: http://www.SQLsharp.com/contact/
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 5 of 210
Installation / Setup
If you do not already have CLR Integration enabled (it is disabled by default when creating a new SQL Server
Instance), then it will be enabled automagically by the setup SQL script.
1) If you do not have the install SQL script for SQL#, or if you want the most recent version, then obtain
the current installation SQL script from the SQL# website at: http://www.SQLsharp.com/
2) Save the SQL script in case you need it later or need to install on more than one machine.
3) Open the SQL script (named SQLsharp_Setup.sql) in SQL Server Management Studio.
4) Be sure to edit the USE statement just under the header comment block by replacing the
{replace_with_DB_name} with the name of the target Database.
5) Add two dashes / hyphens just to the right of the “];” after the DB name to comment out the comment.
6) If you do not want to install one of the optional Assemblies – SQL#_2, SQL#.DB, SQL#.DotNetZip
(Full Version only), SQL#.FileSystem (Full Version only), SQL#.JsonFx, SQL#.Network, SQL#.OS,
SQL#.SgmlReader, SQL#.Twitterizer, SQL#.TypesAndAggregates, SQL#.TypesAndAggregatesPlus,
and SQL#.XML – just update the variables just below the USE statement to equal 0, each of which
follows this form:
SET @InstallSQL#{AssemblyName} = 1;
7) The script will create an Asymmetric Key and a Key-based Login (both in [master]). The Login
provides the ability to set any of the SQL# Assemblies to a security level other than SAFE without
needing to set the Database to TRUSTWORTHY ON. It will also be the owner of the SQL#
Assemblies which will create an App Domain separate from any other potential SQLCLR code that
would be owned by “dbo”. Whether or not any of the SQL# Assemblies can be set to either External
Access or Unrestricted Access depends on what permission this SQL# Login is granted, and that is
determined by the setting of the @MaxAllowedAccessLevel variable (just below the USE statement).
Please see the comments immediately following the “SET @MaxAllowedAccessLevel =” line for a
detailed description of each value.
8) Click on !Execute OR press F5 OR press Control-E (so many choices!) to run the script, and it will
display status information in the “Messages” tab.
9) All SQL# Functions, Stored Procedures, and User-Defined Types reside in the SQL# Schema, so you
might need to GRANT permissions to any Users or Roles that will be using them via:
EXEC SQL#.SQLsharp_GrantPermissions N'UserName_A, Role_B';
Note: this is either a single name or a comma-separated list.
10) Enjoy!
Updating
Internally (not available in Free version)
This method will download the most current SQL# installer from the SQLsharp.com website (no
information from your computer is transmitted to the site, just the version number being upgraded), and save
it in the location that you specify.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 6 of 210
Externally
This method is not preferred as it is not as easy (or cool!) as the internal method using the
SQLsharp_Download Stored Procedure. But if you must, then it does happen to work:
1) Obtain the current installation SQL script from the SQL# website at:
a. Free version: http://www.SQLsharp.com/free/
b. Full version: http://www.SQLsharp.com/full/
2) Save the SQL script in case you need it later or need to install on more than one machine.
3) You do not need to uninstall the previous version as that will be done by the install script
4) Open the SQL script in SQL Server Management Studio.
5) Follow the general installation / setup instructions, noted above, starting at Step 4.
6) Assemblies that have been set to security levels higher than SAFE will be reset to the current security
level (unless it is the main SQL# Assembly, in which case it will always be reset to SAFE as of SQL#
Version 4.0).
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 7 of 210
Character Description
\ Marks the next character as a special character, a literal, a backreference, or an octal escape.
For example, 'n' matches the character "n". '\n' matches a newline character. The sequence '\\'
matches "\" and "\(" matches "(".
^ Matches the position at the beginning of the input string. If the RegExp object's Multiline
property is set, ^ also matches the position following '\n' or '\r'.
$ Matches the position at the end of the input string. If the RegExp object's Multiline property is
set, $ also matches the position preceding '\n' or '\r'.
* Matches the preceding character or subexpression zero or more times. For example, zo*
matches "z" and "zoo". * is equivalent to {0,}.
+ Matches the preceding character or subexpression one or more times. For example, 'zo+'
matches "zo" and "zoo", but not "z". + is equivalent to {1,}.
? Matches the preceding character or subexpression zero or one time. For example, "do(es)?"
matches the "do" in "do" or "does". ? is equivalent to {0,1}
{n} N is a nonnegative integer. Matches exactly n times. For example, 'o{2}' does not match the 'o'
in "Bob," but matches the two o's in "food".
{n,} N is a nonnegative integer. Matches at least n times. For example, 'o{2,}' does not match the
"o" in "Bob" and matches all the o's in "foooood". 'o{1,}' is equivalent to 'o+'. 'o{0,}' is equivalent
to 'o*'.
{n,m} M and n are nonnegative integers, where n <= m. Matches at least n and at most m times. For
example, "o{1,3}" matches the first three o's in "fooooood". 'o{0,1}' is equivalent to 'o?'. Note
that you cannot put a space between the comma and the numbers.
? When this character immediately follows any of the other quantifiers (*, +, ?, {n}, {n,}, {n,m}),
the matching pattern is non-greedy. A non-greedy pattern matches as little of the searched
string as possible, whereas the default greedy pattern matches as much of the searched string
as possible. For example, in the string "oooo", 'o+?' matches a single "o", while 'o+' matches all
'o's.
. Matches any single character except "\n". To match any character including the '\n', use a
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 8 of 210
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 9 of 210
\s Matches any white space character including space, tab, form-feed, and so on. Equivalent to
[ \f\n\r\t\v].
\S Matches any non-white space character. Equivalent to [^ \f\n\r\t\v].
\t Matches a tab character. Equivalent to \x09 and \cI.
\v Matches a vertical tab character. Equivalent to \x0b and \cK.
\w Matches any word character including underscore. Equivalent to '[A-Za-z0-9_]'.
\W Matches any nonword character. Equivalent to '[^A-Za-z0-9_]'.
\xn Matches n, where n is a hexadecimal escape value. Hexadecimal escape values must be
exactly two digits long. For example, '\x41' matches "A". '\x041' is equivalent to '\x04' & "1".
Allows ASCII codes to be used in regular expressions.
\num Matches num, where num is a positive integer. A reference back to captured matches. For
example, '(.)\1' matches two consecutive identical characters.
\n Identifies either an octal escape value or a backreference. If \n is preceded by at least n
captured subexpressions, n is a backreference. Otherwise, n is an octal escape value if n is an
octal digit (0-7).
\nm Identifies either an octal escape value or a backreference. If \nm is preceded by at least nm
captured subexpressions, nm is a backreference. If \nm is preceded by at least n captures, n is
a backreference followed by literal m. If neither of the preceding conditions exists, \nm matches
octal escape value nm when n and m are octal digits (0-7).
\nml Matches octal escape value nml when n is an octal digit (0-3) and m and l are octal digits (0-7).
\un Matches n, where n is a Unicode character expressed as four hexadecimal digits. For example,
\u00A9 matches the copyright symbol (©).
RegEx Options
Also, for all RegEx functions the RegExOptionsList parameter is a pipe-separated list of options that can be
specified in any combination to control how the Regular Expression pattern matching is performed. You can
pass in NULL or empty string ‘’ for “none”. Values are NOT case-sensitive. The valid values are:
Compiled Specifies that the regular expression is compiled to an assembly. This yields
faster execution but increases startup time. Please note that the compiled
definition stays in memory until the App Domain is unloaded.
CultureInvariant Specifies that cultural differences in language are ignored. Ordinarily, the regular
expression engine performs string comparisons based on the conventions of the
current culture. If the CultureInvariant option is specified, it uses the
conventions of the invariant culture.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 10 of 210
ECMAScript Enables ECMAScript-compliant behavior for the expression. This value can be
used only in conjunction with the IgnoreCase and Multiline values. The use of
this value with any other values results in an exception.
ExplicitCapture Specifies that the only valid captures are explicitly named or numbered groups of
the form (?<name>…). This allows unnamed parentheses to act as noncapturing
groups without the syntactic clumsiness of the expression (?:…).
IgnoreCase Specifies case-insensitive matching.
IgnorePatternWhitespace Eliminates unescaped white space from the pattern and enables comments
marked with #. However, the IgnorePatternWhitespace value does not affect or
eliminate white space in character classes
Multiline Multiline mode. Changes the meaning of ^ and $ so they match at the beginning
and end, respectively, of any line, and not just the beginning and end of the
entire string.
RightToLeft Specifies that the search will be from right to left instead of from left to right.
Singleline Specifies single-line mode. Changes the meaning of the dot (.) so it matches
every character (instead of every character except \n).
Examples:
'IgnoreCase' or 'ignorecase|CultureInvariant'
RegEx_CaptureGroup
RegEx_CaptureGroup(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX),
CaptureGroupNumber INT, NotFoundReplacement NVARCHAR(4000), StartAt INT, Length INT,
RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
NOTES:
CaptureGroupNumber >= 0
CaptureGroupNumber of 0 returns the whole capture
NotFoundReplacement can be empty string ‘’, any value, or NULL
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
Length of -1 = Search until the end of the ExpressionToValidate
If input data will never be over 4000 characters, please use RegEx_CaptureGroup4k as that function
offers better performance.
EXAMPLES:
SELECT SQL#.RegEx_CaptureGroup('there were 123 web errors + 5 ftp errors',
'(\d+) (web|ftp) errors', 2, NULL, 1, -1, '')
-- web
SELECT SQL#.RegEx_CaptureGroup('there were 123 web errors + 5 ftp errors',
'(\d+) (web|ftp) errors', 2, NULL, 1, 8, '')
-- NULL
SELECT SQL#.RegEx_CaptureGroup('there were 123 web errors + 5 ftp errors',
'(\d+) (web|ftp) errors', 2, NULL, 15, -1, '')
-- ftp
SELECT SQL#.RegEx_CaptureGroup('errors', '(\d+) (web|ftp) errors', 2, 'Not
Found', 1, -1, '')
-- Not Found
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 11 of 210
RegEx_CaptureGroup4k
RegEx_CaptureGroup4k(ExpressionToValidate NVARCHAR(4000), RegularExpression NVARCHAR(4000),
CaptureGroupNumber INT, NotFoundReplacement NVARCHAR(4000), StartAt INT, Length INT,
RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
NOTES:
Functionally equivalent to RegEx_CaptureGroup except no NVARCHAR(MAX) parameters
Use this function in place of RegEx_CaptureGroup when input data will never be over 4000
characters as this function offers better performance.
RETURNS: TABLE (MatchNum INT, GroupNum INT, Value NVARCHAR(MAX), StartPos INT, EndPos INT,
Length INT)
NOTES:
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
EXAMPLES:
SELECT * FROM SQL#.RegEx_CaptureGroups('phone: 800-555-1212', '((\d{3})-(\d{3})-
(\d{4}))', 1, 'IgnoreCase')
/*
MatchNum GroupNum Value StartPos EndPos Length
1 1 800-555-1212 8 19 12
1 2 800 8 10 3
1 3 555 12 14 3
1 4 1212 16 19 4
*/
RegEx_Escape
RegEx_Escape(ExpressionToEscape NVARCHAR(MAX))
RETURNS: NVARCHAR(MAX)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 12 of 210
Escapes a minimal set of metacharacters (\, *, +, ?, |, {, [, (,), ^, $,., #, and white space) by replacing them with
their escape codes.
NOTES:
See also: RegEx_Unescape
EXAMPLES:
SELECT SQL#.RegEx_Escape('test(*.)')
-- test\(\*\.\)
RegEx_Index
RegEx_Index(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX), StartAt INT,
Length INT, RegExOptionsList NVARCHAR(4000))
RETURNS: INT
Returns the location of the first character of the first match that is found starting at StartAt.
NOTES:
StartAt:
o Must be >= 1
o cannot be greater than the length of ExpressionToValidate
Length:
o 0 = search entire ExpressionToValidate
o cannot be greater than the length of ExpressionToValidate
EXAMPLES:
SELECT SQL#.RegEx_Index('thisAA is a isA fisAA bob', 'is[A]{2}', 1, 0, '')
-- 3
SELECT SQL#.RegEx_Index('thisAA is a isA fisAA bob', 'is[A]{2}', 4, 0, '')
-- 18
SELECT SQL#.RegEx_Index('thisAA is a isA fisAA bob', 'is[A]{2}', 4, 2, '')
-- 0
RegEx_IsMatch
RegEx_IsMatch(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX), StartAt
INT, RegExOptionsList NVARCHAR(4000))
RETURNS: BIT
NOTES:
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
If input data will never be over 4000 characters, please use RegEx_IsMatch4k as that function offers
better performance.
EXAMPLES:
SELECT SQL#.RegEx_IsMatch('zo', 'zo{2}', 1, '')
-- 0
SELECT SQL#.RegEx_IsMatch('zoo', 'zo{2}', 1, '')
-- 1
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 13 of 210
RegEx_IsMatch4k
RegEx_IsMatch4k(ExpressionToValidate NVARCHAR(4000), RegularExpression NVARCHAR(4000), StartAt
INT, RegExOptionsList NVARCHAR(4000))
RETURNS: BIT
NOTES:
Functionally equivalent to RegEx_IsMatch except no NVARCHAR(MAX) parameters
Use this function in place of RegEx_IsMatch when input data will never be over 4000 characters as
this function offers better performance.
RegEx_Match
RegEx_Match(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX), StartAt INT,
RegExOptionsList NVARCHAR(4000))
RETURNS: TABLE (MatchNum INT, Value NVARCHAR(MAX), StartPos INT, EndPos INT, Length INT)
NOTES:
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
Returns the FIRST match; will only return 1 row
EXAMPLES:
SELECT * FROM SQL#.RegEx_Match('This is a test that shows matching', 'th.{2}',
1, '')
--MatchNum Value StartPos EndPos Length
--1 that 16 19 4
SELECT * FROM SQL#.RegEx_Match('This is a test that shows matching', 'th.{2}',
1, 'IgnoreCase')
--MatchNum Value StartPos EndPos Length
--1 This 1 4 4
RegEx_Matches
RegEx_Matches(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX), StartAt
INT, RegExOptionsList NVARCHAR(4000))
RETURNS: TABLE (MatchNum INT, Value NVARCHAR(MAX), StartPos INT, EndPos INT, Length INT)
NOTES:
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
Same as RegEx_Match but returns all matches
EXAMPLES:
SELECT * FROM SQL#.RegEx_Matches('This is a test that shows matching', 'th.{2}',
1, 'IgnoreCase')
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 14 of 210
RegEx_MatchLength
RegEx_MatchLength(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX),
StartAt INT, Length INT, RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
Returns the first match that is found starting at StartAt but only looking as far as Length characters rather than
until the end of the ExpressionToValidate.
NOTES:
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
Length cannot be greater than the length of ExpressionToValidate
EXAMPLES:
SELECT SQL#.RegEx_MatchLength('This is a test that shows matching', 'th.{2}', 1,
20, '')
-- that
SELECT SQL#.RegEx_MatchLength('This is a test that shows matching', 'th.{2}', 1,
10, '')
-- (empty string)
SELECT SQL#.RegEx_MatchLength('This is a test that shows matching', 'th.{2}',
10, 10, '')
-- that
RegEx_MatchSimple
RegEx_MatchSimple(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX),
StartAt INT, RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
NOTES:
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
Returns the first match that is found starting at StartAt but unlike RegEx_MatchLength it will search
until the end of the ExpressionToValidate
If input data will never be over 4000 characters, please use RegEx_MatchSimple4k as that function
offers better performance.
EXAMPLES:
SELECT SQL#.RegEx_MatchSimple('This is a test that shows matching', 'th.{2}', 1,
'IgnoreCase')
-- This
SELECT SQL#.RegEx_MatchSimple('This is a test that shows matching', 'th.{2}',
10, '')
-- that
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 15 of 210
RegEx_MatchSimple4k
RegEx_MatchSimple4k(ExpressionToValidate NVARCHAR(4000), RegularExpression NVARCHAR(4000),
StartAt INT, RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
NOTES:
Functionally equivalent to RegEx_MatchSimple except no NVARCHAR(MAX) parameters
Use this function in place of RegEx_MatchSimple when input data will never be over 4000 characters
as this function offers better performance.
RegEx_Replace
RegEx_Replace(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX),
Replacement NVARCHAR(4000), Count INT, StartAt INT, RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
NOTES:
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
Count cannot be less than -1
Count of -1 = unlimited replacements
Allows for capturing groups using parenthesis (look at the third example) and those groups can be
used in the replacement expression using $ notation
If no matches are found, ExpressionToValidate is returned without changes
If input / output data will never be over 4000 characters, please use RegEx_Replace4k as that
function offers better performance.
EXAMPLES:
SELECT SQL#.RegEx_Replace('This is a test that shows matching', 'th.{2}', 'bob',
2, 1, '')
-- This is a test bob shows matching
SELECT SQL#.RegEx_Replace('This is a test that is edifying', 'is', 'IS', 2, 1,
'')
-- ThIS IS a test that is edifying
SELECT SQL#.RegEx_Replace('This is a test that shows matching',
'(a)\s+(t.{2}t)\s+(that)', 'NOT $3 s$1me ol'' $2 which sometimes', 2, 1, '')
-- This is NOT that same ol' test which sometimes shows matching
SELECT SQL#.RegEx_Replace(N'abacab', N'aa', N'#', -1, 1, NULL)
-- abacab
RegEx_Replace4k
RegEx_Replace4k(ExpressionToValidate NVARCHAR(4000), RegularExpression NVARCHAR(4000),
Replacement NVARCHAR(4000), Count INT, StartAt INT, RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
NOTES:
Functionally equivalent to RegEx_Replace except no NVARCHAR(MAX) parameters
Use this function in place of RegEx_Replace when input / output data will never be over 4000
characters as this function offers better performance.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 16 of 210
RegEx_ReplaceIfMatched
RegEx_ReplaceIfMatched (ExpressionToValidate NVARCHAR(MAX), RegularExpression
NVARCHAR(MAX), Replacement NVARCHAR(4000), NotFoundReplacement NVARCHAR(MAX), Count
INT, StartAt INT, RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
NOTES:
NotFoundReplacement can be empty string ‘’, any value, or NULL
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
Count cannot be less than -1
Count of -1 = unlimited replacements
Allows for capturing groups using parenthesis (look at the third example) and those groups can be
used in the replacement expression using $ notation
If no matches are found, NotFoundReplacement is returned
If input / output data will never be over 4000 characters, please use RegEx_ReplaceIfMatched4k as
that function offers better performance.
EXAMPLES:
SELECT SQL#.RegEx_ReplaceIfMatched(N'abacab', N'a', N'#', N'$$', -1, 1, NULL)
-- #b#c#b
SELECT SQL#.RegEx_ReplaceIfMatched(N'abacab', N'a', N'#', N'$$', 2, 1, NULL)
-- #b#cab
SELECT SQL#.RegEx_ReplaceIfMatched(N'abacab', N'aa', N'#', N'$$', -1, 1, NULL)
-- $$
RegEx_ReplaceIfMatched4k
RegEx_ReplaceIfMatched4k(ExpressionToValidate NVARCHAR(4000), RegularExpression
NVARCHAR(4000), Replacement NVARCHAR(4000), NotFoundReplacement NVARCHAR(4000), Count
INT, StartAt INT, RegExOptionsList NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
NOTES:
Functionally equivalent to RegEx_ReplaceIfMatched except no NVARCHAR(MAX) parameters
Use this function in place of RegEx_ReplaceIfMatched when input / output data will never be over
4000 characters as this function offers better performance.
RegEx_Split
RegEx_Split(ExpressionToValidate NVARCHAR(MAX), RegularExpression NVARCHAR(MAX), Count INT,
StartAt INT, RegExOptionsList NVARCHAR(4000))
RETURNS: TABLE (MatchNum INT, Value NVARCHAR(MAX), StartPos INT, EndPos INT, Length INT)
NOTES:
StartAt >= 1
StartAt cannot be greater than the length of ExpressionToValidate
Count cannot be less than -1
Count of -1 (or 0) = unlimited “parts”
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 17 of 210
Works like String_Split but uses a Regular Expression to break a string into multiple records rather
than a static character or string delimiter
If the “part” is empty (Length = 0), StartPos and EndPos both equal -1
EXAMPLES:
SELECT * FROM SQL#.RegEx_Split('This is a test iff i ever saw one',
'i[fs]{1,2}', 0, 1, '')
/*
MatchNum Value StartPos EndPos Length
1 Th 1 2 2
2 5 5 1
3 a test 8 15 8
4 i ever saw one 19 33 15
*/
RegEx_Unescape
RegEx_Unescape(ExpressionToUnescape NVARCHAR(MAX))
RETURNS: NVARCHAR(MAX)
EXAMPLES:
SELECT SQL#.RegEx_Unescape('test\(\*\.\)')
-- test(*.)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 18 of 210
Strings
For String functions, the @StartIndex input parameter specifies the absolute location in the string
@StringValue to start at. The first position in a string in SQL Server is 1 and that holds true with all of these
SQL# functions; they do NOT start at position 0 (zero). This also holds true of the IndexOf and LastIndexOf
functions that return the position of a string within another string.
The following chart lists the options (not case-sensitive) to be used in any function that accepts a parameter
named @StringCompareOptions. Multiple options, separated by a comma “,” or pipe symbol / vertical bar “|”,
can be used in each case. This chart is taken from the MSDN page for CompareOptions Enumeration.
Option Description
IgnoreKanaType Indicates that the string comparison must ignore the Kana type. Kana type refers to
Japanese hiragana and katakana characters, which represent phonetic sounds in the
Japanese language. Hiragana is used for native Japanese expressions and words,
while katakana is used for words borrowed from other languages, such as "computer"
or "Internet". A phonetic sound can be expressed in both hiragana and katakana. If
this value is selected, the hiragana character for one sound is considered equal to the
katakana character for the same sound.
IgnoreNonSpace Indicates that the string comparison must ignore nonspacing combining characters,
such as diacritics. The Unicode Standard defines combining characters as characters
that are combined with base characters to produce a new character. Nonspacing
combining characters do not occupy a spacing position by themselves when
rendered.
IgnoreSymbols Indicates that the string comparison must ignore symbols, such as white-space
characters, punctuation, currency symbols, the percent sign, mathematical symbols,
the ampersand, and so on.
IgnoreWidth Indicates that the string comparison must ignore the character width. For example,
Japanese katakana characters can be written as full-width or half-width. If this value
is selected, the katakana characters written as full-width are considered equal to the
same characters written as half-width.
Ordinal Indicates that the string comparison must use successive Unicode UTF-16 encoded
values of the string (code unit by code unit comparison), leading to a fast comparison
but one that is culture-insensitive. A string starting with a code unit XXXX16 comes
before a string starting with YYYY16, if XXXX16 is less than YYYY16. This value cannot
be combined with other CompareOptions values and must be used alone.
OrdinalIgnoreCase String comparison must ignore case, then perform an ordinal comparison. This
technique is equivalent to converting the string to uppercase using the invariant
culture and then performing an ordinal comparison on the result. This value cannot
be combined with other CompareOptions values and must be used alone.
StringSort Indicates that the string comparison must use the string sort algorithm. In a string
sort, the hyphen and the apostrophe, as well as other nonalphanumeric symbols,
come before alphanumeric characters.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 19 of 210
RETURNS: BIT
Compares two delimited lists of after the lists have been split into individual items. The lists must have the
same number of elements once split. Meaning, an item from one list cannot match more than one item, even
if the same text, in the other list.
NOTES:
RegExDelimiter
o What to split both lists on
RegExOptionsList
o Please see list of options here
o Option “IgnoreCase” affects only the split, not the comparison
CaseSensitive
o How to compare the lists after being split
o Does not affect the case-sensitivity of the split
NullHandling
o When to return a NULL if either or both StringValue parameters are NULL
o Options are NOT case-sensitive
o Options are:
Empty string ‘’ = never; return FALSE if either or both are NULL
Either = return NULL if either or both are NULL
Both = return NULL only if both are NULL or FALSE is only one is NULL
EXAMPLES:
SELECT SQL#.String_CompareSplitValues('a B', 'b a', ' ', '', 0, '')
-- 1
SELECT SQL#.String_CompareSplitValues('a B', 'b a', '\s+', '', 0, '')
-- 1
SELECT SQL#.String_CompareSplitValues('a B', 'b a', '\s+', '', 1, '')
-- 0
SELECT SQL#.String_CompareSplitValues(NULL, 'b a', '\s+', '', 0, 'either')
-- NULL
SELECT SQL#.String_CompareSplitValues('a B', NULL, '\s+', '', 0, 'both')
-- 0
SELECT SQL#.String_CompareSplitValues(NULL, NULL, '\s+', '', 0, 'both')
-- NULL
SELECT SQL#.String_CompareSplitValues(NULL, NULL, '\s+', '', 0, '')
-- 0
String_Contains
String_Contains(StringValue NVARCHAR(MAX), SearchValue NVARCHAR(4000))
RETURNS: BIT
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 20 of 210
While using the COLLATE clause will likely be more efficient, it might not be as easy to work with. Also keep
in mind that if any SQL is coded with the COLLATE clause it will always be set for that codepage whereas the
String_Contains() function will use the system’s current language setting. Consider the following:
SELECT 1 WHERE 'ABC' LIKE '%a%' COLLATE Latin1_General_100_CS_AS
SELECT 1 WHERE 'ABC' LIKE '%a%' COLLATE Latin1_General_100_CS_AS
OR 'a' = 'A' COLLATE Latin1_General_100_CI_AS
In the second SELECT, the OR condition does not have to specify the COLLATE clause if you want to use
the default collation for the database. The example above would work the same if you had any *CI* collation
set as the database default. FYI: the _CS_ means CaseSensitive whereas the _CI_ means CaseInsensitive.
Specifying COLLATE works only for the expression it is to the right of.
EXAMPLES:
SELECT SQL#.String_Contains('ABC', 'ab')
-- 0
SELECT SQL#.String_Contains('Abacab', 'ab')
-- 1
String_Count
String_Count(StringValue NVARCHAR(MAX), SearchValue NVARCHAR(MAX), StartAt INT,
ComparisonType INT, CountOverlap BIT)
RETURNS: INT
NOTES:
StartAt must be >= 1 and <= the length of StringValue
ComparisonType:
o 1 (case-sensitive)
o 2 (case-INsensitive)
If CountOverlap is set to 0 / False then the search will resume at the end of the previous match.
If CountOverlap is set to 1 / True then the search will continue from the next character after the start
of the previous match.
EXAMPLES:
SELECT SQL#.String_Count('aaAAaaa', 'aa', 1, 2, 0)--insensitive, no ovrlap
-- 3
SELECT SQL#.String_Count('aaAAaaa', 'aa', 1, 2, 1) -- insensitive, overlap
-- 6
SELECT SQL#.String_Count('aaAAaaa', 'aa', 1, 1, 1) -- sensitive, overlap
-- 3
SELECT SQL#.String_Count('aaAAaaa', 'aa', 1, 1, 0) -- sensitive, no ovrlap
-- 2
SELECT SQL#.String_Count('aaAAaaa', 'aa', 3, 1, 1) -- sensitive, overlap
-- 2
String_Cut
String_Cut(StringValue NVARCHAR(MAX), Delimiter NVARCHAR(4000), Fields NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
String_Cut returns a string of the fields specified in Fields from StringValue. String_Cut emulates the UNIX
“cut” command when using the –f flag.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 21 of 210
NOTES:
Delimiter cannot be NULL
IF StringValue IS NULL returns NULL
Empty StringValue returns empty string
IF Delimiter is empty string returns StringValue unchanged
Fields = [BeginField-] | [-EndField] | [BeginField- EndField] | [FieldNum] [,]
EXAMPLES:
SELECT SQL#.String_Cut('one two three four five', ' ', '1,3')
-- one three
SELECT SQL#.String_Cut('one two three four five', ' ', '-2')
-- one two
SELECT SQL#.String_Cut('one two three four five', ' ', '3-')
-- three four five
SELECT SQL#.String_Cut('one two three four five', ' ', '1,2,4-')
-- one two four five
SELECT SQL#.String_Cut('one two three four five', ' ', '-2, 5')
-- one two five
RETURNS: INT
Calculate the number of changes (inserts, updates, deletes, and transpositions of two adjacent characters) it
takes to get from String1 to String2.
NOTES:
NULL input returns NULL.
Calculation will exit if @MaxDistance is reached, rather than continuing to waste CPU and time.
If @MaxDistance < 0 or > the longer of @String1 and @String2, then no real “max” distance.
Comparison assumes same LCID / Locale and sensitity settings as Database’s default Collation.
For more information, see: http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
Also see: String_LevenshteinDistance
EXAMPLES:
SELECT SQL#.String_DamerauLevenshteinDistance(N'Whale', N'Banana', -1);
-- 5
SELECT SQL#.String_DamerauLevenshteinDistance(N'Whale', N'Banana', 2);
-- 3
SELECT SQL#.String_DamerauLevenshteinDistance(N'Whale', N'Whlae', -1);
-- 1
RETURNS: INT
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 22 of 210
Calculate the number of changes (inserts, updates, deletes, and transpositions of two adjacent characters) it
takes to get from String1 to String2.
NOTES:
NULL input returns NULL.
Calculation will exit if @MaxDistance is reached, rather than continuing to waste CPU and time.
If @MaxDistance < 0 or > the longer of @String1 and @String2, then no real “max” distance.
Unlike the non-“Plus” version, this version allows for customizing how a character is determined to be
equal to another. Sensitivity to Case, Accents, etc can be turned on and off, similar to being able to
specify a collation dynamically, if that were possible.
Use this version if you need the comparison to use a “custom” Collation, one that does not match
your databases default Collation.
@StringCompareOptions
o Comma “,” or Pipe “|” separated list of options
o NULL or empty string ‘’ = None = everything sensitive (but not binary / ordinal)
o ‘Database_Default’ (not case sensitive; cannot be combined with other values) uses
sensitivity settings associated with default Collation of Database where SQL# is installed.
o Full list of options is shown at the beginning of the Strings section of this manual.
@LCID options:
o -1 = Invariant culture
o 0 = LCID that is associated with default Collation of Database where SQL# is installed.
o Valid values found at: https://msdn.microsoft.com/en-us/library/cc233982.aspx (Language ID)
For more information, see: http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
See also: String_LevenshteinDistancePlus
EXAMPLES:
SELECT SQL#.String_DamerauLevenshteinDistancePlus(N'WhAle', -1, N'Whlae', '',
1033);
-- 2
SELECT SQL#.String_DamerauLevenshteinDistancePlus(N'WhAle', -1, - N'Whlae',
'iGnorecAsE', 1033);
-- 1
SELECT SQL#.String_DamerauLevenshteinDistancePlus(N'WhAle', -1, - N'Whläe',
'iGnorecAsE', 1033);
-- 2
SELECT SQL#.String_DamerauLevenshteinDistancePlus(N'WhAle', -1, - N'Whläe',
'iGnorecAsE,IgnoreNonSpace', 1033);
-- 1
String_EndsWith
String_EndsWith(StringValue NVARCHAR(MAX), SearchValue NVARCHAR(4000), ComparisonType INT)
RETURNS: BIT
NOTES:
ComparisonType:
o 1 (case-sensitive)
o 2 (case-INsensitive)
See discussion of COLLATE clause in String_Contains
EXAMPLES:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 23 of 210
String_Equals
String_Equals(StringValueA NVARCHAR(MAX), StringValueB NVARCHAR(MAX))
RETURNS: BIT
NOTES:
See discussion of COLLATE clause in String_Contains
EXAMPLES:
SELECT SQL#.String_Equals('Plainsong', 'plainsong')
-- 0
SELECT SQL#.String_Equals('Plainsong', 'Plainsong')
-- 1
RETURNS: INT
Finds the first occurrence of a string within another string which is parsed into fixed-width elements
NOTES:
Returns 0 if not found
ReturnValue:
o NOT case-sensitive
o Options:
PositionFromBeginning: the position, starting at the beginning of the
StringToSearch regardless of StartAt
PositionFromStartAt: the position relative to the StartAt value
ElementNumber: which element within the set that was parsed into fixed-width
elements
EXAMPLES:
SELECT SQL#.String_FixedWidthIndex('1234567890', '34', 0, 1, 0, 'ElementNumber')
-- 2
SELECT SQL#.String_FixedWidthIndex('1234567890', '45', 0, 1, 0, 'ElementNumber')
-- 0
SELECT SQL#.String_FixedWidthIndex('zzz1234567890', '34', 0, 4, 0,
'ElementNumber') -- 2
SELECT SQL#.String_FixedWidthIndex('zzz1234567890', '34', 0, 4, 0,
'PositionFromBeginning') -- 6
SELECT SQL#.String_FixedWidthIndex('zzz1234567890', '34', 0, 4, 0,
'PositionFromStartAt') -- 3
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 24 of 210
NOTES:
Final ElementValue might be less than Width characters if there are not Width characters left in the
StringToSplit
EXAMPLES:
SELECT * FROM SQL#.String_FixedWidthSplit('1234567890', 2, 1)
/*
ElementNumber ElementValue
1 12
2 34
3 56
4 78
5 90
*/
String_IndexOf
String_IndexOf(StringValue NVARCHAR(4000), SearchValue NVARCHAR(4000), StartIndex INT,
ComparisonType INT)
RETURNS: INT
String_IndexOf returns the position of the first occurrence of SearchValue in StringValue starting at
StartIndex. If no occurrence of SearchValue is found within that range, String_IndexOf returns 0 (zero).
NOTES:
StartIndex >= 1
StartIndex <= LEN(StringValue)
ComparisonType:
o 1 (case-sensitive)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 25 of 210
o 2 (case-INsensitive)
EXAMPLES:
SELECT SQL#.String_IndexOf('Sound of Music', 's', 1, 1)
-- 12
SELECT SQL#.String_IndexOf('Sound of Music', 's', 1, 2)
-- 1
SELECT SQL#.String_IndexOf('Sound of Music', 'o', 1, 1)
-- 2
SELECT SQL#.String_IndexOf('Sound of Music', 'o', 5, 1)
-- 7
String_InitCap
String_InitCap(StringValue NVARCHAR(MAX))
RETURNS: NVARCHAR(MAX)
EXAMPLE:
SELECT SQL#.String_InitCap('the boy with the thorn in his side')
-- The Boy With The Thorn In His Side
String_IsNumeric
String_IsNumeric(StringValue NVARCHAR(MAX), NumberTypeMask INT)
RETURNS: BIT
Determines if the StringValue is a number as defined by NumberTypeMask. Works much like the T-SQL
built-in ISNUMERIC() but can handle more than 8000 bytes, can handle more numeric formats, and can
distinguish between numeric formats.
NOTES:
NumberTypeMask:
o A bit-mask value used to specify one or more (or all) numeric formats
o Number Format Values:
1 = No thousands separator, Period as radix point, optional Scientific Notation.
Example: [+/-]12345[.67][e/E+/-10]
2 = No thousands separator, Comma as radix point, optional Scientific Notation.
Example: [+/-]12345[,67][e/E+/-10]
4 = Comma as thousands separator, Period as radix point, optional Currency symbol.
Example: [[+/-$]or[$+/-]][12,]345[.67]
8 = Period as thousands separator, Comma as radix point, optional Currency symbol.
Example: [[+/-$]or[$+/-]][12.]345[,67]
16 = Space as thousands separator, Period as radix point, optional Currency symbol.
Example: [[+/-$]or[$+/-]][12 ]345[.67]
32 = Space as thousands separator, Comma as radix point, optional Currency
symbol. Example: [[+/-$]or[$+/-]][12 ]345[,67]
63 = ALL formats
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 26 of 210
Above chart shows all valid Currency symbols (as taken from Microsoft SQL Server Books Online)
Additional info: http://en.wikipedia.org/wiki/Decimal_separator
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 27 of 210
EXAMPLE:
SELECT SQL#.String_IsNumeric('$123,121.55', 4)
-- 1
SELECT SQL#.String_IsNumeric('$123,121.55', 8)
-- 0
String_Join
String_Join(SQL NVARCHAR(MAX), Separator NVARCHAR(4000), JoinOption INT)
RETURNS: NVARCHAR(MAX)
String_Join will create a single string from the rows of a single string column. If you want to combine
numbers, you must convert them to a string datatype in the SQL. The SQL can be any SELECT statement as
long as it returns a single column of a text datatype. The SELECT statement can even be from a Temp Table
(but not a Table Variable).
NOTES:
Separator can be more than 1 character
CombineOption:
o 1 = for Keep Empty Entries
o 2 = Remove Empty Entries
Depending on your situation, you might be able to get away with this:
DECLARE @JoinedString VARCHAR(MAX)
SET @JoinedString = ''
SELECT @JoinedString = @JoinedString + alias.Column + ','
FROM SchemaName.TableName alias
EXAMPLE:
SELECT so.name INTO #temp_name FROM sys.objects so
SELECT SQL#.String_Join('SELECT name FROM #temp_name', ',', 1)
DROP TABLE #temp_name
GO
-- sysrowsetcolumns,sysrowsets,sysallocunits,sysfiles1,...
String_LastIndexOf
String_LastIndexOf(StringValue NVARCHAR(MAX), SearchValue NVARCHAR(4000), StartIndex INT,
ComparisonType INT)
RETURNS: INT
String_LastIndexOf returns the position of the last occurrence of SearchValue in StringValue starting at
StartIndex and proceeding backwards, towards the start of the string. If no occurrence of SearchValue is
found within that range, String_LastIndexOf returns 0 (zero).
NOTES:
StartIndex
o >= 1
o <= LEN(StringValue)
o Where search begins at and proceeds backwards
ComparisonType:
o 1 (case-sensitive)
o 2 (case-INsensitive)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 28 of 210
EXAMPLES:
SELECT SQL#.String_LastIndexOf('Temptation', 'T', LEN('Temptation'), 1)
-- 1
SELECT SQL#.String_LastIndexOf('Temptation', 'T', LEN('Temptation'), 2)
-- 7
SELECT SQL#.String_LastIndexOf('Temptation', 't', LEN('Temptation'), 1)
-- 7
SELECT SQL#.String_LastIndexOf('Temptation', 't', 5, 1)
-- 5
RETURNS: INT
Calculate the number of changes (inserts, updates, and deletes) it takes to get from String1 to String2.
NOTES:
NULL input returns NULL.
Calculation will exit if @MaxDistance is reached, rather than continuing to waste CPU and time.
If @MaxDistance < 0 or > the longer of String1 and String2, then no real “max” distance.
Comparison assumes same LCID / Locale and sensitity settings as Database’s default Collation.
For more information, see: http://en.wikipedia.org/wiki/Levenshtein_distance
Also see: String_DamerauLevenshteinDistance
EXAMPLES:
SELECT SQL#.String_LevenshteinDistance(N'Whale', N'Banana', -1);
-- 5
SELECT SQL#.String_LevenshteinDistance(N'Whale', N'Banana', 3);
-- 4
SELECT SQL#.String_LevenshteinDistance(N'Whale', N'Whlae', -1);
-- 2
RETURNS: INT
Calculate the number of changes (inserts, updates, and deletes) it takes to get from String1 to String2.
NOTES:
NULL input returns NULL.
Calculation will exit if @MaxDistance is reached, rather than continuing to waste CPU and time.
If @MaxDistance < 0 or > the longer of @String1 and @String2, then no real “max” distance.
Unlike the non-“Plus” version, this version allows for customizing how a character is determined to be
equal to another. Sensitivity to Case, Accents, etc can be turned on and off, similar to being able to
specify a collation dynamically, if that were possible.
Use this version if you need the comparison to use a “custom” Collation, one that does not match
your databases default Collation.
@StringCompareOptions
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 29 of 210
EXAMPLES:
SELECT SQL#.String_LevenshteinDistancePlus(N'ABC' + NCHAR(304), N'ABci', -1,
N'none', 0x0409);
-- 2
SELECT SQL#.String_LevenshteinDistancePlus(N'ABC' + NCHAR(304), N'ABci', -1,
N'IgnoreCase', 0x0409);
-- 1
SELECT SQL#.String_LevenshteinDistancePlus(N'ABC' + NCHAR(304), N'ABci', -1,
N'IgnoreCase|IgnoreNonSpace', 0x0409);
-- 0
SELECT SQL#.String_LevenshteinDistancePlus(N'ABC' + NCHAR(304), N'ABci', -1,
N'IgnoreCase', 0x041f);
-- 0
SELECT SQL#.String_LevenshteinDistancePlus(N'ABC' + NCHAR(304), N'ABci', -1,
N'database_default', 0);
-- 1 (database default Collation = Latin1_General_100_CI_AS_SC)
String_Newline
String_Newline(EOLType NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
String_Newline returns the newline character(s) for the particular OS / End-Of-Line Type that is specified.
NOTES:
EOLType can be:
o CRLF, WIN, WINDOWS, DOS, or OS/2
o LF or UNIX
o CR or MAC
o FF
o NEL, 390, OS/390, or EBCDIC
o HTML
o XHTML
EOLType is not case-sensitive
EXAMPLES:
PRINT 'This is a test of ' +
SQL#.String_Newline('win') +
'how newlines' +
SQL#.String_Newline('html') +
'work in SQL strings.'
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 30 of 210
This is a test of
how newlines<br>work in SQL strings.
String_NthIndexOf
String_NthIndexOf(StringValue NVARCHAR(MAX), Search NVARCHAR(MAX), StartAt INT, NthOccurance
INT, ComparisonType INT, CountOverlap BIT)
RETURNS: INT
String_NthIndexOf finds the location of the specified occurance of Search in StringValue. It returns 0 if not
found.
NOTES:
If StringValue is NULL, 0 is returned
Search cannot be NULL or empty string
StartAt >= 1
StartAt <= LEN(StringValue)
NthOccurance >= 1
ComparisonType = 1 (case-sensitive) or 2 (case-INsensitive)
EXAMPLES:
SELECT SQL#.String_NthIndexOf('aaa AAaa', 'aa', 1, 3, 1, 1)
-- StartAt 1, 3rd Occurance, case Sensitive, do count OverLaps
-- 8
SELECT SQL#.String_NthIndexOf('aaa AAaa', 'aa', 1, 3, 2, 1)
-- StartAt 1, 3rd Occurance, case INsensitive, do count OverLaps
-- 6
SELECT SQL#.String_NthIndexOf('aaa AAaa', 'aa', 1, 3, 2, 0)
-- StartAt 1, 3rd Occurance, case INsensitive, do NOT count OverLaps
-- 8
SELECT SQL#.String_NthIndexOf('aaa AAaa', 'aa', 2, 3, 2, 1)
-- StartAt 2, 3rd Occurance, case INsensitive, do count OverLaps
-- 7
SELECT SQL#.String_NthIndexOf('aaa AAaa', 'aa', 1, 3, 1, 0)
-- StartAt 1, 3rd Occurance, case INsensitive, do NOT count OverLaps
-- 0
RETURNS: NVARCHAR(MAX)
Combines both PadLeft and PadRight, essentially centering StringValue based on StringWidth. It allows for
choosing different characters for each side.
NOTES:
StringWidth >= LEN(StringValue)
LeftPadCharacter and RightPadCharacter can only be a single character; any characters after the
first one will be ignored.
FavorLeftOrRight:
o NOT case-sensitive
o ‘L’ or ‘R’
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 31 of 210
o ‘L’ will place string just left of center when sides are uneven
o ‘R’ will place string just right of center when sides are uneven
EXAMPLES:
SELECT SQL#.String_PadBoth(N'Test', 8, N'$', N'%', N'R');
-- $$Test%%
SELECT SQL#.String_PadBoth(N'Test', 9, N'$', N'%', N'L');
-- $$Test%%%
SELECT SQL#.String_PadBoth(N'Test', 9, N'$', N'%', N'r');
-- $$$Test%%
String_PadLeft
String_PadLeft(StringValue NVARCHAR(MAX), StringWidth INT, PadCharacter NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
String_PadLeft returns a string of StringWidth characters with StringValue right-justified and padded on the
left with PadCharacter.
NOTES:
StringWidth >= LEN(StringValue)
PadCharacter can only be a single character; any characters after the first one will be ignored.
EXAMPLE:
SELECT SQL#.String_PadLeft('Kathy'' Song', 30, '*')
-- *******************Kathy' Song
String_PadRight
String_PadRight(StringValue NVARCHAR(MAX), StringWidth INT, PadCharacter NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
String_PadRight returns a string of StringWidth characters with StringValue left-justified and padded on the
right with PadCharacter.
NOTES:
StringWidth >= LEN(StringValue)
PadCharacter can only be a single character; any characters after the first one will be ignored.
EXAMPLE:
SELECT SQL#.String_PadRight('Colorwheel', 30, '-')
-- Colorwheel********************
String_Replace
String_Replace(Expression NVARCHAR(MAX), Find NVARCHAR(MAX), Replacement NVARCHAR(MAX))
RETURNS: NVARCHAR(MAX)
Works the same as the builtin T-SQL REPLACE function but accepts NVARCHAR(MAX) for all parameters.
EXAMPLES:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 32 of 210
String_Split
String_Split(StringValue NVARCHAR(MAX), Separator NVARCHAR(4000), SplitOption INT)
String_Split takes a delimited string (based on the Separator) and returns a table of its elements after
removing the Separator.
NOTES:
Separator can be more than 1 character
SplitOption:
o 1 = for Keep Empty Entries
o 2 = Remove Empty Entries
For strings that will never be over 4000 characters, use String_Split4k, which is faster.
EXAMPLES:
SELECT * FROM SQL#.String_Split('12,1,45,646,8978,90,4,3,6,15', ',', 1)
/*
1 12
2 1
3 45
4 646
5 8978
6 90
7 4
8 3
9 6
10 15
*/
SELECT * FROM SQL#.String_Split('Bob<br><br>Sally<br><br>', '<br>', 1)
/*
1 Bob
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 33 of 210
2
3 Sally
4
5
*/
SELECT * FROM SQL#.String_Split('Bob<br><br>Sally<br><br>', '<br>', 2)
/*
1 Bob
2 Sally
*/
String_Split4k
String_Split4k(StringValue NVARCHAR(4000), Separator NVARCHAR(4000), SplitOption INT)
Identical to String_Split except for the datatype for StringValue (input) and SplitVal (output). This function is
much faster than String_Split for input strings of no more than 4000 characters. Only use String_Split with
strings longer than 4000 characters, or if you cannot guarantee that they will not be over 4000 characters.
Please see String_Split for Notes and Examples.
String_SplitIntoFields (deprecated)
Change references for String_SplitIntoFields to be String_SplitResultIntoFields !!
PROC: Result set is the NVARCHAR(MAX) field specified in @Query broken into fields based on
@RegExDelimiter
NOTES:
Change references for String_SplitIntoFields to be String_SplitResultIntoFields !!
@Query:
o must return a string field (CHAR, VARCHAR, NCHAR, NVARCHAR, TEXT, NTEXT) as the
first column of a SELECT statement
o Any additional columns returned by @Query will be ignored
@RegExDelimiter is a full Regular Expression (See RegEx section)
@ColumnNames:
o Optional parameter
o Comma-separated list of values that will be used to name the columns of the result set
o Extra spaces around each name will be trimmed
o If more fields are in the data than specified in ColumnNames then additional fields will be
named as FieldN where N is the field number
o If more fields are specified in ColumnNames than in the first row of the result set then extra
Column Names will be ignored
o If not set or set to NULL then all field names will be FieldN where N is the field number
starting with 1
@DataTypes:
o Optional parameter
o Value is NOT case-sensitive
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 34 of 210
o Comma-separated list of values that will be used to specify the datatype of the columns of the
result set
o If more fields are in the data than specified in DataTypes then additional fields will be set to
NVARCHAR(MAX)
o If more fields are specified in DataTypes than in the first row of the result set then extra
values will be ignored
o If not set or set to NULL then all field datatypes will be set to NVARCHAR(MAX)
o Empty value in source data will return empty string for (N)(VAR)CHAR / XML datatypes, 0x00
for (VAR)BINARY, and NULL for number / date datatypes.
o Currently, the TIME and DATETIMEOFFSET datatypes do not work properly.
Number of fields returned in result set is based on first row of data
After first row of data, rows with more fields will have the additional fields ignored (see example)
After number of fields to return is set, rows with fewer fields will return empty strings for the missing
fields (see example)
See also: File_SplitIntoFields and INET_SplitIntoFields
EXAMPLES:
CREATE TABLE #SplitTest (Column1 VARCHAR(MAX), Column2 VARCHAR(MAX))
/*
Name Title Alias Field4 Field5
-------- -------- -------- -------- --------
Value1 Value2 Value3 Value4
NewValue1 NewValue2 NewValue3 Value4
Another1 Another2 Another3
a b c d e
*/
Splits a delimited set of Key-Value pairs into a result set. A Common use of this is a HTTP Query String
which has Key-Value pairs (key=value) separated by ampersands (&).
NOTES:
PairSeparator:
o 1 or more characters that separates each set of Key-Value pairs.
o Typically this is an ampersand (&)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 35 of 210
KeyValueSeparator:
o 1 or more characters that separates each Key and Value
o Typically this is an equal-sign (=)
RemoveEmptyPairs:
o If set to 1, removes Pairs where both Key and Value are empty
o Example of empty KeyValuePair: &=&
Trim:
o These are NOT case-sensitive
o “Key” does a Trim on just the Key
o “Value” does a Trim on just the Value
o “Both” does a Trim on both Key and Value
o NULL or empty string ‘’ else does nothing
Decode:
o These are NOT case-sensitive
o “Key” does a URIDecode on just the Key
o “Value” does a URIDecode on just the Value
o “Both” does a URIDecode on both Key and Value
o NULL or empty string ‘’ does nothing
o Use “Value” or “Both” when splitting a HTTP Query String
Unquote:
o Use this only if the Values are quoted
o Single character to remove from Value only (has no effect on Key)
o The character is only removed if it is present on both sides of the Value
EXAMPLES:
DECLARE @String NVARCHAR(MAX)
SET @String = 'asd=234&=& asd = 234
&qw234234&asd=234&qw=234234&&qw=234234&asd=234&qw=234234&as%3dd=2%203%3e4&f=asd"
&g="234"'
SELECT * FROM SQL#.String_SplitKeyValuePairs(@String, '&', '=', 0, null, null,
null) -- row 2 is empty
SELECT * FROM SQL#.String_SplitKeyValuePairs(@String, '&', '=', 1, null, null,
null) -- empty row is gone
SELECT * FROM SQL#.String_SplitKeyValuePairs(@String, '&', '=', 1, 'key', null,
null) -- row 2 key is trimmed
SELECT * FROM SQL#.String_SplitKeyValuePairs(@String, '&', '=', 1, 'key',
'value', null) -- row 8 value is decoded
SELECT * FROM SQL#.String_SplitKeyValuePairs(@String, '&', '=', 1, 'key',
'value', '"') -- row 10 value is unquoted
String_StartsWith
String_StartsWith(StringValue NVARCHAR(4000), SearchValue NVARCHAR(4000), ComparisonType INT)
RETURNS: BIT
NOTES:
ComparisonType:
o 1 (case-sensitive)
o 2 (case-INsensitive)
See discussion of COLLATE clause in String_Contains
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 36 of 210
EXAMPLES:
SELECT SQL#.String_StartsWith('Hey Nineteen', 'hey', 1)
-- 0
SELECT SQL#.String_StartsWith('Hey Nineteen', 'hey', 2)
-- 1
String_Trim
String_Trim(StringValue NVARCHAR(MAX))
RETURNS: NVARCHAR(MAX)
EXAMPLE:
SELECT '*' + SQL#.String_Trim(' Deacon Blues ') + '*'
-- *Deacon Blues*
RETURNS: NVARCHAR(MAX)
This works like String_Trim, but instead of removing whitespace characters, it removes all occurrences of the
characters passed in via @CharsToTrim.
EXAMPLE:
SELECT SQL#.String_TrimChars('"''aasasa34985as"sa398475as''"', '"''as')
-- 34985as"sa398475
RETURNS: NVARCHAR(MAX)
This works like the built-in RTRIM function, but instead of removing whitespace characters, it removes all
occurrences of the characters passed in via @CharsToTrim until it reaches the first character NOT in
@CharsToTrim.
EXAMPLE:
SELECT SQL#.String_TrimEnd('"''aasasa34985as"sa398475as''"', '"''as')
-- "'aasasa34985as"sa398475
RETURNS: NVARCHAR(MAX)
This works like the built-in LTRIM function, but instead of removing whitespace characters, it removes all
occurrences of the characters passed in via @CharsToTrim until it reaches the first character NOT in
@CharsToTrim.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 37 of 210
EXAMPLE:
SELECT SQL#.String_TrimStart('"''aasasa34985as"sa398475as''"', '"''as')
-- 34985as"sa398475as'"
String_TryParseToInt
String_TryParseToInt(StringValue NVARCHAR(4000), TargetDataType NVARCHAR(15), Culture
NVARCHAR(10))
RETURNS: BIGINT
NOTES:
Works nearly identically to TRY_PARSE which was introduced in SQL Server 2012
If StringValue contains a number that is valid for the TargetDataType, the converted value will be
returned
If StringValue contains non-numeric characters or is not valid for the TargetDataType, NULL will be
returned
TargetDataType:
o NOT case-sensitive
o VALUES: TINYINT, SMALLINT, INT, BIGINT
Culture is optional; pass in empty string ‘’ to use system default
NULL input returns NULL
EXAMPLES:
SELECT SQL#.String_TryParseToInt('123 456', 'int', '')
-- NULL
SELECT SQL#.String_TryParseToInt('123 456', 'int', 'en-us')
-- NULL
SELECT SQL#.String_TryParseToInt('123 456', 'int', 'fr-fr')
-- 123456
SELECT SQL#.String_TryParseToInt('123,456', 'INT', 'en-us')
-- 123456
SELECT SQL#.String_TryParseToInt('123,456', 'int', 'fr-fr')
-- NULL
String_WordWrap
String_WordWrap(StringValue NVARCHAR(MAX), LineWidth INT, Separator NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
String_WordWrap returns a string broken into lines of LineWidth characters with Separator between each line.
EXAMPLE:
DECLARE @String NVARCHAR(MAX)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 39 of 210
Math
As with any of the other SQL# functions, any string options sent into a function are NOT case-
sensitive; mixed-case options are shown here for easier reading.
Math_BitwiseLeftShift
Math_BitwiseLeftShift(TheValue BIGINT, BitsToShift INT)
RETURNS: BIGINT
NOTES:
Shifts TheValue the number of bit positions to the left as specified by BitsToShift
Returns NULL if either input parameter is NULL
Bit position: 8 7 6 5 4 3 2 1 0
Decimal Equivalents: 256 128 64 32 16 8 4 2 1
Binary Value: 1 0 0 1 0
Decimal Value: 16 + 2 = 18
EXAMPLES:
SELECT SQL#.Math_BitwiseLeftShift(1, 4); -- 16
SELECT SQL#.Math_BitwiseLeftShift(2, 3); -- 16
SELECT SQL#.Math_BitwiseLeftShift(3, 2); -- 12 (3=slots 0 & 1; 12=slots 2 & 3)
SELECT SQL#.Math_BitwiseLeftShift(18, 2); -- 72 (18=slots 1 & 4; 72=slots 6 & 3)
Math_BitwiseRightShift
Math_BitwiseRightShift(TheValue BIGINT, BitsToShift INT)
RETURNS: BIGINT
NOTES:
Shifts TheValue the number of bit positions to the right as specified by BitsToShift
Returns NULL if either input parameter is NULL
Bit position: 8 7 6 5 4 3 2 1 0
Decimal Equivalents: 256 128 64 32 16 8 4 2 1
Binary Value: 1 0 1 1 0 0 0 0
Decimal Value: 128 + 32 + 16 = 176
EXAMPLES:
SELECT SQL#.Math_BitwiseRightShift(12, 2); -- 3
SELECT SQL#.Math_BitwiseRightShift(16, 3); -- 2
SELECT SQL#.Math_BitwiseRightShift(176, 2); -- 44 (44 = slots 5, 3, & 2)
Math_CompoundAmortizationSchedule
Math_CompoundAmortizationSchedule(LoanAmount FLOAT, AnnualInterestRate FLOAT, YearsOfLoan INT,
PaymentsPerYear INT, LoanStartDate DATETIME, OptionalExtraPayment FLOAT)
NOTES:
LoanAmount must be >= 0
YearsOfLoan must be >= 1
PaymentsPerYear must be >= 1
OptionalExtraPayment must be >= 0
EXAMPLE:
SELECT * FROM SQL#.Math_CompoundAmortizationSchedule(100000, 5.5, 2, 12,
'1/1/2006', 0)
E
x
Pay- t Total Cumula- Total Pay-
ment Beginning Pay- r Pay- Ending tive Total Pay- ments
Num Date Balance ment a ment Principle Interest Balance Interest Interest ments Left
1 2/1/2006 100000.00 4409.57 0 4409.57 3951.24 458.33 96048.76 458.33 5829.53 24 23
2 3/1/2006 96048.76 4409.57 0 4409.57 3969.35 440.22 92079.41 898.55 5829.53 24 22
3 4/1/2006 92079.41 4409.57 0 4409.57 3987.54 422.03 88091.87 1320.58 5829.53 24 21
4 5/1/2006 88091.87 4409.57 0 4409.57 4005.82 403.75 84086.05 1724.33 5829.53 24 20
5 6/1/2006 84086.05 4409.57 0 4409.57 4024.18 385.39 80061.87 2109.72 5829.53 24 19
6 7/1/2006 80061.87 4409.57 0 4409.57 4042.62 366.95 76019.25 2476.67 5829.53 24 18
7 8/1/2006 76019.25 4409.57 0 4409.57 4061.15 348.42 71958.1 2825.09 5829.53 24 17
8 9/1/2006 71958.10 4409.57 0 4409.57 4079.76 329.81 67878.34 3154.9 5829.53 24 16
9 10/1/2006 67878.34 4409.57 0 4409.57 4098.46 311.11 63779.88 3466.01 5829.53 24 15
10 11/1/2006 63779.88 4409.57 0 4409.57 4117.25 292.32 59662.63 3758.33 5829.53 24 14
11 12/1/2006 59662.63 4409.57 0 4409.57 4136.12 273.45 55526.51 4031.78 5829.53 24 13
12 1/1/2007 55526.51 4409.57 0 4409.57 4155.07 254.5 51371.44 4286.28 5829.53 24 12
13 2/1/2007 51371.44 4409.57 0 4409.57 4174.12 235.45 47197.32 4521.73 5829.53 24 11
14 3/1/2007 47197.32 4409.57 0 4409.57 4193.25 216.32 43004.07 4738.05 5829.53 24 10
15 4/1/2007 43004.07 4409.57 0 4409.57 4212.47 197.1 38791.6 4935.15 5829.53 24 9
16 5/1/2007 38791.60 4409.57 0 4409.57 4231.78 177.79 34559.82 5112.94 5829.53 24 8
17 6/1/2007 34559.82 4409.57 0 4409.57 4251.17 158.4 30308.65 5271.34 5829.53 24 7
18 7/1/2007 30308.65 4409.57 0 4409.57 4270.66 138.91 26037.99 5410.25 5829.53 24 6
19 8/1/2007 26037.99 4409.57 0 4409.57 4290.23 119.34 21747.76 5529.59 5829.53 24 5
20 9/1/2007 21747.76 4409.57 0 4409.57 4309.89 99.68 17437.87 5629.27 5829.53 24 4
21 10/1/2007 17437.87 4409.57 0 4409.57 4329.65 79.92 13108.22 5709.19 5829.53 24 3
22 11/1/2007 13108.22 4409.57 0 4409.57 4349.49 60.08 8758.73 5769.27 5829.53 24 2
23 12/1/2007 8758.73 4409.57 0 4409.57 4369.43 40.14 4389.3 5809.41 5829.53 24 1
24 1/1/2008 4389.30 4409.42 0 4409.42 4389.30 20.12 0 5829.53 5829.53 24 0
Math_Constant
Math_Constant(ConstantName NVARCHAR(4000))
RETURNS: FLOAT
NOTES:
1. SpeedOfLight
2. Gravity
3. GravitationalAcceleration
4. ElectronMass
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 41 of 210
5. ProtonMass
6. NeutronMass
7. AtomicMassUnit
8. ElectronCharge
9. Planck
10. Boltzmann
11. MagneticPermeability
12. DielectricPermittivity
13. ClassicalElectronRadius
14. FineStructure
15. BohrRadius
16. Rydberg
17. FluxQuantum
18. BohrMagneton
19. ElectronMagnetMoment
20. NuclearMagneton
21. ProtonMagnetMoment
22. NeutronMagnetMoment
23. ComptonElectronWavelength
24. ComptonProtonWavelength
25. Stefan-Boltzmann
26. Avogadro
27. IdealGasVolume
28. Gas
29. Faraday
30. QuantumHoleResistance
EXAMPLES:
SELECT SQL#.Math_Constant('SpeedOfLight')
-- 299792458
SELECT SQL#.Math_Constant('GAS')
-- 8.31451
Math_Convert
Math_Convert(BaseNumber FLOAT, From NVARCHAR(4000), To NVARCHAR(4000))
RETURNS: FLOAT
You can convert between any of the units of measurement within a group, but not between groups (duh!).
NOTES:
Returns NULL if any input parameter is NULL
Distance & Length
1. Nanometer
2. Micrometer
3. Millimeter
4. Centimeter
5. Meter
6. Kilometer
7. Inch
8. Foot
9. Yard
10. Mile
Temperature
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 42 of 210
1. Kelvin
2. Celsius
3. Fahrenheit
4. Rankine
5. Reaumur
Computer Data Size
1. Bit
2. Byte
3. Kilobyte
4. Megabyte
5. Gigabyte
6. Terabyte
7. Petabyte
EXAMPLES:
SELECT SQL#.Math_Convert(1.0, 'yard' ,'mile')
-- 0.000568181818181818
SELECT SQL#.Math_Convert(1.0, 'mile' ,'centimeter')
-- 160934.4
SELECT SQL#.Math_Convert(-40.0, 'fahrenheit' ,'celsius')
-- -40
SELECT SQL#.Math_Convert(0, 'kelvin' ,'celsius')
-- -273.15
Math_Cosh
Math_Cosh(BaseNumber FLOAT)
RETURNS: FLOAT
EXAMPLE:
SELECT SQL#.Math_Cosh(1.5)
-- 2.35240961524325
Math_CubeRoot
Math_CubeRoot(BaseNumber FLOAT)
RETURNS: FLOAT
NOTES:
Same as Math_NthRoot(@Number, 3) but faster
Same as PostgreSQL function: cbrt
EXAMPLE:
SELECT SQL#.Math_CubeRoot(27)
-- 3
SELECT SQL#.Math_CubeRoot(28)
-- 3.03658897187566
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 43 of 210
Math_Factorial
Math_Factorial(BaseNumber INT)
RETURNS: INT
EXAMPLE:
SELECT SQL#.Math_Factorial(10)
-- 3628800
Math_FormatDecimal
Math_FormatDecimal(TheNumber DECIMAL(38, 18), NumberFormat NVARCHAR(4000), Culture
NVARCHAR(10))
RETURNS: NVARCHAR(4000)
Returns a string representing the number in the specified format and optional culture.
NOTES:
NumberFormat
o Standard formats: http://msdn.microsoft.com/en-us/library/dwhawy9k(VS.80).aspx
o Custom formats: http://msdn.microsoft.com/en-us/library/0c899ak8(VS.80).aspx
Culture
o Optional, use empty string (‘’) to default to “current culture”
o Available culture names: http://msdn.microsoft.com/en-
US/library/system.globalization.cultureinfo(v=vs.80).aspx
Essentially the same as the new FORMAT command in SQL Server 2012:
http://msdn.microsoft.com/en-us/library/hh213505(v=sql.110).aspx
EXAMPLES:
SELECT SQL#.Math_FormatDecimal(12345678.0987654, 'C2', 'FR-fr')
-- 12 345 678,10 €
SELECT SQL#.Math_FormatDecimal(12345678.0987654, 'C4', 'ja-jp')
-- ¥12,345,678.0988
SELECT SQL#.Math_FormatDecimal(12345678.0987654, 'C', '')
-- $12,345,678.10
SELECT SQL#.Math_FormatDecimal(12345678.0987654, '### - ### . #|#|# // #', '')
-- 12345 - 678 . 0|9|8 // 8
RETURNS: NVARCHAR(4000)
Returns a string representing the number in the specified format and optional culture.
NOTES:
NumberFormat
o Standard formats: http://msdn.microsoft.com/en-us/library/dwhawy9k(VS.80).aspx
o Custom formats: http://msdn.microsoft.com/en-us/library/0c899ak8(VS.80).aspx
Culture
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 44 of 210
EXAMPLES:
SELECT SQL#.Math_FormatFloat(123.123192, 'N', 'ja-jp')
-- 123.12
SELECT SQL#.Math_FormatFloat(123.123192, 'p', 'FR-fr')
-- 12 312,32 %
SELECT SQL#.Math_FormatFloat(123.123192, 'P', '')
-- 12,312.32 %
RETURNS: NVARCHAR(4000)
Returns a string representing the number in the specified format and optional culture.
NOTES:
NumberFormat
o Standard formats: http://msdn.microsoft.com/en-us/library/dwhawy9k(VS.80).aspx
o Custom formats: http://msdn.microsoft.com/en-us/library/0c899ak8(VS.80).aspx
Culture
o Optional, use empty string (‘’) to default to “current culture”
o Available culture names: http://msdn.microsoft.com/en-
US/library/system.globalization.cultureinfo(v=vs.80).aspx
Essentially the same as the new FORMAT command in SQL Server 2012:
http://msdn.microsoft.com/en-us/library/hh213505(v=sql.110).aspx
EXAMPLES:
SELECT SQL#.Math_FormatInteger(9223372036854775807, 'N', 'FR-fr')
-- 9 223 372 036 854 775 807,00
SELECT SQL#.Math_FormatInteger(123112, 'X', '')
-- 1E0E8
SELECT SQL#.Math_FormatInteger(9223372036854775807, '## - ## / ## h ## k ## l ##
(##)bob', '')
-- 9223372 - 03 / 68 h 54 k 77 l 58 (07)bob
RETURNS: FLOAT
NOTES:
From the MSDN documentation:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 45 of 210
This operation complies with the remainder operation defined in Section 5.1 of ANSI/IEEE Std 754-
1985; IEEE Standard for Binary Floating-Point Arithmetic; Institute of Electrical and Electronics
Engineers, Inc; 1985.
The IEEERemainder method is not the same as the modulus operator. Although both return the
remainder after division, the formulas they use are different. The formula for
theIEEERemainder method is:
EXAMPLES:
SELECT SQL#.Math_IEEERemainder(25.4, 4.5), 25.4 % 4.5
-- -1.6 2.9
SELECT SQL#.Math_IEEERemainder(-16.3, 4.1), -16.3 % 4.1
-- 0.0999999999999979 04.0
Math_IsPrime
Math_IsPrime(BaseNumber BIGINT)
RETURNS: BIT
EXAMPLE:
SELECT SQL#.Math_IsPrime(12318237133333)
-- 1
RETURNS: FLOAT
NOTES:
If using Root value of 3, use Math_CubeRoot instead as it is slightly faster
EXAMPLES:
SELECT SQL#.Math_NthRoot(27, 3)
-- 3
SELECT SQL#.Math_NthRoot(27.5, 3.5)
-- 2.57773288800724
Math_RandomRange
Math_RandomRange(Seed INT, LowerBound INT, UpperBound INT)
RETURNS: INT
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 46 of 210
NOTES:
Seed can be NULL
Random number generation might not work as you anticipate; please see examples and notes below
LowerBound must be less than or equal to the @UpperBound
EXAMPLE:
SELECT SQL#.Math_RandomRange(NULL, -10, 10), RAND()
SELECT SQL#.Math_RandomRange(NULL, -10, 10), RAND(4)
SELECT SQL#.Math_RandomRange(NULL, -10, 10), RAND(4), RAND()
SELECT RAND(),
SQL#.Math_RandomRange(NULL, 1, 8)
FROM SQL#.Util_GenerateInts(1, 200, 2) ints
Randomize functions, in native T-SQL or even in .Net languages do not produce truly random numbers. How
they are used plays a large role in how they generate numbers. For example, to run RAND() by itself across
several executions will produce a different number each time. However if you pass in a seed, such as calling
RAND(4) will produce the same number each time. One nuance that is not obvious is that the number
generate by RAND() will only be random if called only once in a batch—yes, in a batch, not just a single
query. To see the effect of this, try the top three examples above. Run each one independently several
times. Then, run all three at the same time several times. You will notice that once RAND() and RAND(4) are
combined in the same batch (such as when highlighting just the top 2 SELECT statements and executing) the
RAND() function works differently than when only the first SELECT statement above is ran several times.
The Math_RandomRange function provides something that the native RAND() function cannot: changing
values between executions and even sometimes within a single execution in a result set of more than one
row. The output shown below the SELECT statements is the first six rows returned from the fourth SELECT
statement above (the one with the FROM clause). As you can see, the RAND() function returns the same
value across all rows, whether or not a seed value is passed in. Across several executions of this query the
same numbers are always produced for; although if you removed the RAND(ints.IntNum) column the RAND()
column would produce a different number each time, but it would still be the same across all rows. Now,
looking at the two Math_RandomRange columns (RR) we can see that when passing in a see value, the
return values are different across each row, but they will also be same the values across multiple executions
of the query, just like we see with the RAND(ints.IntNum) function call. What is truly different here is the
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 47 of 210
Math_RandomRange call when passing in NULL as the seed value. In this case we get two benefits over the
T-SQL RAND() function: first is that across several executions of the query the return values will be different,
and second is that sometimes the return values per row can differ—something not possible even when using
RAND() by itself in a query! When you run the fourth query above, look through all 200 rows returned and
you can see that the value changes at least once. The fifth (and final) query above is a simple side-by-side
comparison of this so you can see more clearly.
Math_Sinh
Math_Sinh(BaseNumber FLOAT)
RETURNS: FLOAT
EXAMPLE:
SELECT SQL#.Math_Sinh(1.5)
-- 2.12927945509482
Math_Tanh
Math_Tanh(BaseNumber FLOAT)
RETURNS: FLOAT
EXAMPLE:
SELECT SQL#.Math_Tanh(1.5)
-- 0.905148253644866
Math_Truncate
Math_Truncate(BaseNumber FLOAT, DecimalPlaces TINYINT)
RETURNS: FLOAT
NOTES:
This does not round up or down; it merely chops the value off at the specified decimal place
This is the same as the PostgreSQL function: trunc
EXAMPLE:
SELECT SQL#.Math_Truncate(123.4567, 2)
-- 123.45
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 48 of 210
Network
The INET functions reside in the SQL#.Network assembly. The following assemblies require the
SQL#.Network assembly to be installed in order to use them: SQL#.DB.
If you use any of the functions that access the file system or network, then this assembly will need a security
setting of EXTERNAL_ACCESS (2). You can set this by executing the following query:
If you do not want to have this assembly in your system at all, you can do either of the following:
Do not install the SQL#.Network assembly by setting the @InstallSQL#Network variable (towards
the top of the script) to 0 before installing
Uninstall the assembly by running:
EXEC SQL#.SQLsharp_Uninstall N'SQL#.Network'
Please note that when accessing the file system, the Operating System user account that will be used is the
one that is currently running (i.e. “log on as”) the main SQL Server process (it might be Local System Account
or an account created specifically for SQL Server).
INET_AddressToNumber
INET_AddressToNumber(IPAddress NVARCHAR(4000))
RETURNS: BIGINT
Converts standard four-part dotted IP Address (IPv4) into a single numerical equivalent. This function mirrors
(mostly) INET_ATON in MySQL and ip2long in PHP.
NOTES:
IF IPAddress IS NULL, is an empty string, or is not a valid IP Address, NULL is returned
See also: INET_NumberToAddress
EXAMPLES:
SELECT SQL#.INET_AddressToNumber('192.168.1.100')
-- 3232235876
SELECT SQL#.INET_AddressToNumber('192.168.1.300')
-- NULL
RETURNS: VARBINARY(8000)
Retrieves a file from the specified URI either as a scalar value OR to a file.
NOTES:
URI:
o Is the full location of the file, starting with the protocol (“http://”, etc.)
o If NULL or empty string ‘’ a NULL will be returned
FileName:
o IF NULL or empty string ‘’ the contents of the remote file will be returned as the scalar value
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 49 of 210
o IF a value, it should be the full path to the filename that will be created from the contents of
the remote file
o IF a value, scalar value returned is 0x00
Downloading directly can also be done via INET_GetWebPages but this is easier if you don’t need all
of the options available in GetWebPages or if you want to download directly to a file.
EXAMPLES:
SELECT SQL#.INET_DownloadFile('http://google.com/images/logos/ps_logo2.png', '')
-- 0x89504E470D0A1A0A0000000D494844520000016C0000007E08020000008F94BCCA...
SELECT SQL#.INET_DownloadFile('http://google.com/images/logos/ps_logo2.png',
'c:\GoogleLogo.png')
-- 0x00
DECLARE @HTML VARCHAR(MAX)
SELECT @HTML = CONVERT(VARCHAR(MAX),
SQL#.INET_DownloadFile('http://www.google.com', ''))
SELECT @HTML
RETURNS: NVARCHAR(4000)
NOTES:
Address must begin with “ftp://”
Options for FTPCommand:
o del | delete | DeleteFile
o mk | mkdir | MakeDirectory
o rm | rmdir | RemoveDirectory
o ren | rename
FTPCommand options are NOT case-sensitive
RenameTo is only used and required if FTPCommand = ren | rename
Return value is completion status
EXAMPLES:
SELECT SQL#.INET_FTPDo('ftp://sqlsharp.com/favicon.ico', 'xxxx', 'xxxx', 'ren',
0, 'favicon.txt')
RETURNS: NVARCHAR(MAX)
NOTES:
This is for ASCII / Text files only; this command does NOT work with Binary files or VARBINARY data
Address must begin with “ftp://”
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 50 of 210
EXAMPLES:
SELECT SQL#.INET_FTPGet('ftp://sqlsharp.com/ ', 'xxxx', 'xxxx', 'dir', 0, 0)
SELECT SQL#.INET_FTPGet('ftp://sqlsharp.com/index.html', 'xxxx', 'xxxx', 'get',
0, 0)
SELECT SQL#.INET_FTPGet('ftp://sqlsharp.com/index.html', 'xxxx', 'xxxx', 'get',
0, 100)
RETURNS: VARBINARY(MAX)
NOTES:
This is mainly for Binary files or VARBINARY data; if used for ASCII files, it will NOT do the
translation of OS specific items such as CRLF <=> LF
Address must begin with “ftp://”
Options for @FTPCommand:
o get | recv | DownloadFile
o ls | ListDirectory
o dir | ListDirectoryDetails
FTPCommand options are NOT case-sensitive
ContentOffset is how many bytes from the beginning of the file to skip. This number has to be >= 0
and if > 0 then FTP will use the RESTART command which can resume a previously stopped
download.
SQL Server Integration Services (SSIS) can FTP a file from a server, but only to disk, not to a local
variable and hence not directly to a column in a table, nor does SSIS support incremental downloads.
Sometimes an FTP error is thrown (The remote server returned an error: (503) Bad sequence of
commands.), just try again and it should work.
EXAMPLES:
DECLARE @File VARBINARY(MAX)
SELECT @File = SQL#.INET_FTPGetBinary('ftp://www.domain.com/file.zip', 'login',
'passwd', 'get', 0, 0)
SELECT @File = SQL#.INET_FTPGetBinary('ftp://www.domain.com/file.zip', 'login',
'passwd', 'get', 0, 100)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 51 of 210
RETURNS: NVARCHAR(4000)
NOTES:
If BinaryMode is set to False / 0, it will NOT do the translation of OS specific items such as CRLF <=>
LF
Address must begin with “ftp://”
Options for @FTPCommand:
o get | recv | DownloadFile
o ls | ListDirectory
o dir | ListDirectoryDetails
FTPCommand options are NOT case-sensitive
FileHandling values:
o 0 – do NOT overwrite an existing file – if the file already exists, you will get an FTP error ( The
remote server returned an error: (451) Local error in processing.)
o 1 – overwrite existing files
o 2 – Incremental download – if the file already exists, autodetect where to start the download
from in the remote file to “resume” the download
EXAMPLES:
SELECT SQL#.INET_FTPGetFile('ftp://www.domain.com/file.zip', 'login', 'passwd',
'get', 0, 1, 'C:\file.zip', 0)
RETURNS: NVARCHAR(4000)
NOTES:
This is for ASCII / Text files only; this command does NOT work with Binary files or VARBINARY data
Address must begin with “ftp://”
Options for FTPCommand:
o app | append | AppendFile
o put | send | UploadFile
FTPCommand options are NOT case-sensitive
Return value is completion status
SQL Server Integration Services (SSIS) can FTP a file to a server, but only from disk, not from a local
variable and hence not directly from a column in a table.
EXAMPLES:
SELECT SQL#.INET_FTPPut('ftp://sqlsharp.com/test.txt', 'xxxx', 'xxxx', 'put', 0,
'this is a test, duh!')
RETURNS: NVARCHAR(4000)
NOTES:
This is mainly for Binary files or VARBINARY data; if used for ASCII files, it will NOT do the
translation of OS specific items such as CRLF <=> LF
Address must begin with “ftp://”
Options for FTPCommand:
o app | append | AppendFile
o put | send | UploadFile
FTPCommand options are NOT case-sensitive
Return value is completion status
SQL Server Integration Services (SSIS) can FTP a file to a server, but only from disk, not from a local
variable and hence not directly from a column in a table.
EXAMPLES:
DECLARE @File VARBINARY(MAX)
RETURNS: NVARCHAR(4000)
NOTES:
If BinaryMode is set to True / 1, it will NOT do the translation of OS specific items such as CRLF <=>
LF
Address must begin with “ftp://”
Options for FTPCommand:
o app | append | AppendFile
o put | send | UploadFile
FTPCommand options are NOT case-sensitive
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 53 of 210
EXAMPLES:
SELECT SQL#.INET_FTPPutFile('ftp://www.domain.com/file.zip', 'login', 'passwd',
'put', 0, 1, 'C:\file.zip')
RETURNS: NVARCHAR(4000)
EXAMPLE:
SELECT SQL#.INET_GetHostName('209.73.186.238')
-- f1.www.vip.re3.yahoo.com
RETURNS: NVARCHAR(50)
EXAMPLE:
SELECT SQL#.INET_GetIPAddress('google.com')
-- 74.125.65.147
EXAMPLE:
SELECT * FROM SQL#.INET_GetIPAddressList('google.com')
--74.125.65.147
--74.125.65.99
--74.125.65.103
--74.125.65.104
--74.125.65.105
--74.125.65.106
RETURNS: TABLE (num INT, line_num INT, content_encoding NVARCHAR(50), content_length BIGINT,
content_type NVARCHAR(50), Server NVARCHAR(500), Content NVARCHAR(MAX), IsFromCache BIT,
LastModified DATETIME, StatusCode INT, StatusDescription NVARChAR(1000), ResponseUri
NVARCHAR(4000), ContentBinary VARBINARY(MAX), ResponseHeaders XML)
NOTES:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 54 of 210
EXAMPLES:
SELECT * FROM SQL#.INET_GetWebPages('http://www.yahoo.com/', 0, 0, 5, -1, -1,
NULL, NULL, NULL, 'Auto')
/*
1 209 -1 text/html; charset=utf-8 <html><head>
<title>Yahoo!</title> <meta http-equiv="...
*/
SELECT * FROM SQL#.INET_GetWebPages('http://www.yahoo.com/', 1, 0, 5, -1, -1,
NULL, NULL, NULL, 'Auto')
/*
1 1 -1 text/html; charset=utf-8 <html><head>
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 55 of 210
1 2 -1 text/html; charset=utf-8
<title>Yahoo!</title>
1 3 -1 text/html; charset=utf-8 <meta http-
equiv="Content-Type" content="text/html; charset=UTF-8">
...
*/
INET_HTMLDecode
INET_HTMLDecode(EncodedHTML NVARCHAR(MAX))
RETURNS: NVARCHAR(MAX)
EXAMPLES:
SELECT SQL#.INET_HTMLDecode('<b>test</b>')
-- <b>test</b>
INET_HTMLEncode
INET_HTMLEncode(DecodedHTML NVARCHAR(MAX), WhiteSpaceHandling NVARCHAR(4000),
ContinuousEncoding BIT)
RETURNS: NVARCHAR(MAX)
Encodes a string, translating characters either reserved for HTML mark-up or special characters into their
HTML-specific values.
NOTES:
WhiteSpaceHandling:
o This option only controls how white-space (spaces and/or returns, but not tabs) are
translated; all other applicable characters will always be translated
o Value cannot be NULL
o Value is NOT case-sensitive
o Valid values are:
‘None’ does not encode spaces or returns
‘Spaces’ encodes only spaces
‘Returns’ encodes only returns (\r\n, \r, and \n)
‘Both’ encodes both spaces and returns
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 56 of 210
ContinuousEncoding set to True / 1 will encode values already encoded (i.e. starting with an
ampersand (&)). If set to False / 0, values already encoded will not have their ampersand turned into
&
EXAMPLES:
DECLARE @HTML NVARCHAR(MAX)
INET_IsValidIPAddress
INET_IsValidIPAddress(IPAddress NVARCHAR(4000))
RETURNS: BIT
Validates whether supplied IPAddress represents a valid IPv4 IP Address is proper four-part dot-notation with
each octect being between 0 and 255.
EXAMPLES:
SELECT SQL#.INET_IsValidIPAddress('192.168.1.100')
-- 1
SELECT SQL#.INET_IsValidIPAddress('192.168.1.300')
-- 0
INET_NumberToAddress
INET_NumberToAddress(IPNumber BIGINT)
RETURNS: NVARCHAR(4000)
Converts a numerical IP Address equivalent to a standard four-part dotted IP Address (IPv4). This function
mirrors (mostly) INET_NTOA in MySQL and long2ip in PHP.
NOTES:
IF IPNumber IS NULL, < 0, or > 4294967295, NULL is returned
See also: INET_AddressToNumber
EXAMPLES:
SELECT SQL#.INET_NumberToAddress(3232235876)
-- 192.168.1.100
SELECT SQL#.INET_NumberToAddress(4294967296)
-- null
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 57 of 210
NOTES:
PacketSize BETWEEN 1 AND 65500
TimeOut BETWEEN 1 AND 10240
TTL BETWEEN 1 AND 10240
Iterations BETWEEN 1 AND 2048
EXAMPLE:
SELECT * FROM SQL#.INET_Ping('www.yahoo.com', 300, 1200, 20, 0, 5)
/*
1 Success 37 69.147.114.210 300
2 Success 147 69.147.114.210 300
3 Success 31 69.147.114.210 300
4 Success 141 69.147.114.210 300
5 Success 33 69.147.114.210 300
*/
RETURNS: FLOAT
NOTES:
PacketSize BETWEEN 1 AND 65500
TimeOut BETWEEN 1 AND 10240
TTL BETWEEN 1 AND 10240
Return value is Number of Milliseconds
EXAMPLE:
SELECT SQL#.INET_PingTime('www.yahoo.com', 3000, 1200, 200, 0)
-- 43
PROC: Result set is each row of delimited text returned by @URI, broken into fields based on
@RegExDelimiter.
NOTES:
@URI:
o cannot be NULL or empty string
o location (file or page) should respond with delimited text
@Timeout:
o How many seconds to wait for a response before timing out
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 58 of 210
EXAMPLES:
EXEC SQL#.INET_SplitIntoFields 'http://www.place.tld/file.csv', -1, ','
-- split a comma-separated response, starting with the first row returned,
-- using "Field"# as the column names, and NVARCHAR(MAX) as all datatypes
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 59 of 210
-- using "OrderID" and "OrderDate" for the first two column-names and
-- "Field"# for any remaining column-names, and setting the datatypes for
-- the first two columns to be INT and DATETIME while any remaining
-- columns will be NVARCHAR(MAX)
INET_URIDecode
INET_URIDecode(EncodedURI NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
EXAMPLES:
SELECT
SQL#.INET_URIDecode('http://www.test.tld/file%20with%20space.aspx?test=one%20two
')
-- http://www.test.tld/file with space.aspx?test=one two
RETURNS: NVARCHAR(4000)
Decodes a string, translating URI-encoded characters into their decoded values. Unlike INET_URIDecode, it
will also decode Unicode characters that were encoded with the non-standard %uXXYY encoding.
INET_URIDecodePlus also has the option of trapping errors inline and reporting them via the return value as
opposed to throwing a hard-error and failing like the regular INET_URIDecode does.
NOTES:
ErrorReplacement:
o Only used if TrapErrorsInline is set to 1
o Will be the return value if EncodedURI produces an error
o Can be NULL, empty string (‘’), or any replacement string
o Can include optional replacement tag of {SQL#ErrorMessage} which will contain the actual
error text
o Replacement tag {SQL#ErrorMessage} is case-sensitive
EXAMPLES:
SELECT SQL#.INET_URIDecodePlus(N'bob+%ec', 0, '')
-- SQL error!
SELECT SQL#.INET_URIDecodePlus(N'bob+%8f', 1, 'error: {SQL#ErrorMessage}')
-- error: Invalid URI: There is an invalid sequence in the string.
SELECT SQL#.INET_URIDecodePlus(N'bob+%8f', 1, NULL)
-- NULL
SELECT SQL#.INET_URIDecodePlus(N'bob+%u00a4', 0, '')
-- bob ¤
INET_URIEncode
INET_URIEncode(DecodedURI NVARCHAR(MAX))
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 60 of 210
RETURNS: NVARCHAR(MAX)
Encodes a URI, translating special characters into their safe / appropriate values except for characters need
to make the URI work, such as: /, :, ?, &, +, and #.
EXAMPLES:
SELECT SQL#.INET_URIEncode('http://www.test.tld/file with space.aspx?test=one
two')
-- http://www.test.tld/file%20with%20space.aspx?test=one%20two
INET_URIEncodeData
INET_URIEncodeData(DecodedURIData NVARCHAR(MAX))
RETURNS: NVARCHAR(MAX)
Encodes a URI data string, translating special characters into their safe / appropriate values including URI
special characters such as: /, :, ?, &, +, and #.
EXAMPLES:
SELECT SQL#.INET_URIEncodeData('http://www.test.tld/file with
space.aspx?test=one two')
-- https%3A%2F%2Ffanyv88.com%3A443%2Fhttp%2Fwww.test.tld%2Ffile%20with%20space.aspx%3Ftest%3Done%20two
INET_URIGetInfo
INET_URIGetInfo(URI NVARCHAR(4000))
NOTES:
A NULL URI value will NOT return a row
EXAMPLES:
SELECT AbsolutePath, Query FROM
SQL#.INET_URIGetInfo('http://www.SQLsharp.com/path/page.php?test=1')
-- /path/page.php ?test=1
) tab
CROSS APPLY SQL#.INET_URIGetInfo(tab.TheURI) info
INET_URIGetLeftPart
INET_URIGetLeftPart(URI NVARCHAR(4000), PartialType NVARCHAR(50))
RETURNS: NVARCHAR(4000)
NOTES:
PartialType:
o Values are NOT case-sensitive
o Valid values are:
Authority
Path
Query
Scheme
EXAMPLES:
SELECT
SQL#.INET_URIGetLeftPart('http://www.someplace.www/path/page.php?var1=sql&var2=s
harp', 'Scheme')
-- http://
SELECT
SQL#.INET_URIGetLeftPart('http://www.someplace.www/path/page.php?var1=sql&var2=s
harp', 'Authority')
-- http://www.someplace.www
SELECT
SQL#.INET_URIGetLeftPart('http://www.someplace.www/path/page.php?var1=sql&var2=s
harp', 'Path')
-- http://www.someplace.www/path/page.php
SELECT
SQL#.INET_URIGetLeftPart('http://www.someplace.www/path/page.php?var1=sql&var2=s
harp', 'Query')
-- http://www.someplace.www/path/page.php?var1=sql&var2=sharp
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 62 of 210
Miscellaneous
Util_CRC32
Util_CRC32(BaseData VARBINARY(MAX))
RETURNS: BIGINT
EXAMPLES:
SELECT SQL#.Util_CRC32(CONVERT(VARBINARY(MAX), some_text_field))
SELECT photo.LargePhotoFileName,
SQL#.Util_CRC32(photo.LargePhoto) AS 'CRC32'
FROM AdventureWorks.Production.ProductPhoto photo
/*
LargePhotoFileName CRC32
-------------------- -------
no_image_available_large.gif 1776513168
racer02_black_f_large.gif 3582859478
racer02_black_large.gif 1272921550
racer02_blue_f_large.gif 414335965
*/
Util_Deflate
Util_Deflate(DataToCompress VARBINARY(MAX))
RETURNS: VARBINARY(MAX)
NOTES:
Be sure to test the data first as some file types, such as Zip archives and some image formats, are
already compressed and actually become larger when put through this function. You will also want to
compare the results with the Util_GZip function as in some cases that can provide better results than
Util_Deflate.
EXAMPLES:
SELECT SQL#.Util_Deflate(CONVERT(VARBINARY, 'This is a test'))
-- 0xEDBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC1...
RETURNS: BIGINT
NOTES:
Forces an immediate full garbage collection of just the SQL Server-specific CLR Host.
Does not affect the main Windows CLR Host.
Returns the number of bytes of memory that have been released by this particular garbage collection.
See also: Util_GetTotalMemory
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 63 of 210
EXAMPLES:
SELECT SQL#.Util_GarbageCollect();
-- 27802144
Util_GenerateDateTimeRange
Util_GenerateDateTimeRange(StartDateTime DATETIME, EndDateTime DATETIME, Step INT, StepType
NVARCHAR(4000))
NOTES:
Step <> 0
StepType IN (year, month, day, hour, minute, second, millisecond)
EXAMPLES:
SELECT * FROM SQL#.Util_GenerateDateTimeRange('1/1/2007', '1/31/2007', 7, 'day')
/*
1 2007-01-01 00:00:00.000
2 2007-01-08 00:00:00.000
3 2007-01-15 00:00:00.000
4 2007-01-22 00:00:00.000
5 2007-01-29 00:00:00.000
*/
Util_GenerateDateTimes
Util_GenerateDateTimes(StartDateTime DATETIME, TotalDateTimes INT, Step INT, StepType
NVARCHAR(4000))
NOTES:
Step <> 0
TotalDateTimes >= 0
StepType IN (year, month, day, hour, minute, second, millisecond)
EXAMPLES:
SELECT * FROM SQL#.Util_GenerateDateTimes('1/1/2007', 6, 2, 'week')
/*
1 2007-01-01 00:00:00.000
2 2007-01-15 00:00:00.000
3 2007-01-29 00:00:00.000
4 2007-02-12 00:00:00.000
5 2007-02-26 00:00:00.000
6 2007-03-12 00:00:00.000
*/
Util_GenerateFloatRange
Util_GenerateFloatRange(StartNum FLOAT, EndNum FLOAT, Step FLOAT)
NOTES:
Step <> 0
EXAMPLES:
SELECT * FROM SQL#.Util_GenerateFloatRange(.456, 2.2345, .354)
/*
1 0.456
2 0.81
3 1.164
4 1.518
5 1.872
6 2.226
*/
Util_GenerateFloats
Util_GenerateFloats(StartNum FLOAT, TotalNums INT, Step FLOAT)
NOTES:
Step <> 0
TotalNums >= 0
EXAMPLES:
SELECT * FROM SQL#.Util_GenerateFloats(4.3, 5, .01231)
/*
1 4.3
2 4.31231
3 4.32462
4 4.33693
5 4.34924
*/
Util_GenerateIntRange
Util_GenerateIntRange(StartNum INT, EndNum INT, Step INT)
NOTES:
Step <> 0
EXAMPLES:
SELECT * FROM SQL#.Util_GenerateIntRange(-5, 5, 2)
/*
1 -5
2 -3
3 -1
4 1
5 3
*/
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 65 of 210
Util_GenerateInts
Util_GenerateInts(StartNum INT, TotalNums INT, Step INT)
NOTES:
Step <> 0
TotalNums >= 0
EXAMPLES:
SELECT * FROM SQL#.Util_GenerateInts(1001, 5, 33)
/*
1 1001
2 1034
3 1067
4 1100
5 1133
*/
Util_GetTotalMemory
Util_GetTotalMemory()
RETURNS: BIGINT
NOTES:
Returns the total number of bytes being used by the SQL Server-specific CLR Host.
Does not include the main Windows CLR Host.
See also: Util_GarbageCollect
EXAMPLES:
SELECT SQL#.Util_GetTotalMemory();
-- 29960704
Util_GUnzip
Util_GUnzip(DataToDecompress VARBINARY(MAX))
RETURNS: VARBINARY(MAX)
NOTES:
Use for data compressed with Util_GZip
NULL input returns NULL
EXAMPLES:
SELECT CONVERT(VARCHAR, SQL#.Util_GUnzip(SQL#.Util_GZip(CONVERT(VARBINARY, 'This
is a test'))))
-- This is a test
Util_GZip
Util_GZip(DataToCompress VARBINARY(MAX))
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 66 of 210
RETURNS: VARBINARY(MAX)
NOTES:
Be sure to test the data first as some file types, such as Zip archives and some image formats, are
already compressed and actually become larger when put through this function. You will also want to
compare the results with the Util_Deflate function as in some cases that can provide better results
than Util_GZip.
NULL or 0x input returns NULL
EXAMPLES:
SELECT SQL#.Util_GZip(CONVERT(VARBINARY, 'This is a test'))
-- 0x1F8B0800000000000400EDBD07601C499625262F6DC...
Util_Hash
Util_Hash(Algorithm NVARCHAR(50), BaseData VARBINARY(MAX))
RETURNS: NVARCHAR(4000)
NOTES:
Algorithm = MD5, SHA1, SHA256, SHA384, or SHA512
Algorithm is NOT case-sensitive
See also the native T-SQL HashBytes function. It has the following algorithms: MD2, MD4, MD5,
SHA, and SHA1. However, it returns a VARBINARY instead of an NVARCHAR.
EXAMPLES:
SELECT SQL#.Util_Hash('SHA512', CONVERT(VARBINARY(MAX), some_text_field))
SELECT photo.LargePhotoFileName,
SQL#.Util_Hash('sha256', photo.LargePhoto) AS 'SHA256'
FROM AdventureWorks.Production.ProductPhoto photo
/*
LargePhotoFileName SHA256
-------------------- -------
no_image_available_large.gif
F304005422457A5967287AD82C2E64909093EF5F2FC7E1E41A2D465213E0B969
racer02_black_f_large.gif
12FB5792202A5685CDF53A35EC58B12DF1EE1E9366F1C8D78BC322DC7E22111F
racer02_black_large.gif
B6A9F3B96023BA479AA91D3987D3E38A74055245BD7B83E0387E2982E690730D
racer02_blue_f_large.gif
82544FDB4615A9DF969B959341A27E5161B1BC2AAA3C6743C0A836F6A8CBC4E9
*/
Util_HashBinary
Util_HashBinary(Algorithm NVARCHAR(50), BaseData VARBINARY(MAX))
RETURNS: VARBINARY(8000)
NOTES:
Algorithm = MD5, SHA1, SHA256, SHA384, or SHA512
Algorithm is NOT case-sensitive
See also the native T-SQL HashBytes function. It has the following algorithms: MD2, MD4, MD5,
SHA, and SHA1. It also returns a VARBINARY.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 67 of 210
EXAMPLES:
SELECT SQL#.Util_HashBinary('SHA512', CONVERT(VARBINARY(MAX), 'test!'))
--
0x49CD017D5AFF930CC9636D2BFBA95C9C319C7164A330ECCE35EC23271643C4BD1623BE510F25D5
EFCC4B031C5D68C25F908636A106A41D29F5657A0759CF0687
Util_Inflate
Util_Inflate(DataToDecompress VARBINARY(MAX))
RETURNS: VARBINARY(MAX)
NOTES:
Use for data compressed with Util_Deflate
EXAMPLES:
SELECT CONVERT(VARCHAR, SQL#.Util_Inflate(SQL#.Util_Deflate(CONVERT(VARBINARY,
'This is a test'))))
-- This is a test
Util_IsValidCC
Util_IsValidCC(CCNumber NVARCHAR(4000), CCType NVARCHAR(4000))
RETURNS: BIT
Determines if a Credit Card number is valid ONLY FOR the following types of Credit Cards:
AmericanExpress, Diners Club, Discover, MasterCard, and Visa.
NOTES:
This does NOT determine in any way if the Credit Card number is active or anything else about the
number outside of it being a possible number that one of those companies would use
CCNumber can have dashes or just the numbers; it is the same either way
CCType can be one of the following values: empty string / ‘’, amex, diners, disc, mc, visa
CCType is not case-sensitive; ‘MC’ and ‘mc’ work just the same
If CCType is an empty string / ‘’ then it will evaluate the validity of the number based on the first few
digits and the length of the number against each of those companies’ rules as each company is
different in those respects
The Visa test number is: 4111111111111111
If the CCType is not an empty string then the number will be evaluated only for that particular
company, and hence is more accurate (meaning, you can know somebody is lying, or just made a
mistake, if they enter in a number starting with 4 that is a valid Visa number but yet they selected
‘amex’ as the CCType. If CCType is ‘’ and they enter in a valid Visa number it will pass as valid but
that same valid Visa number will fail as invalid if the CCType is ‘amex’ or ‘disc’
EXAMPLES:
SELECT SQL#.Util_IsValidCC('4111111111111111', '')
-- 1
SELECT SQL#.Util_IsValidCC('4111111111111111', 'visa')
-- 1
SELECT SQL#.Util_IsValidCC('4111111111111111', 'amex')
-- 0
SELECT SQL#.Util_IsValidCC('6111111111111111', 'visa')
-- 0
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 68 of 210
Util_IsValidCheckRoutingNumber
Util_IsValidCheckRoutingNumber(RoutingNumber NVARCHAR(4000))
RETURNS: BIT
Determines if a Check Routing Number (also known as the ABA Routing Number) is valid.
NOTES:
This does NOT determine in any way if the Routing Number is active or has ever been used; it can
only check that it is a number that “could” be used
RoutingNumber can have dashes, spaces, or just the numbers
EXAMPLES:
SELECT SQL#.Util_IsValidCheckRoutingNumber('271972572')
-- 1
SELECT SQL#.Util_IsValidCheckRoutingNumber('371972572')
-- 0
Util_IsValidConvert
Util_IsValidConvert(ValueToConvert NVARCHAR(MAX), ConvertToDataTypes NVARCHAR(4000),
DecimalPrecision SMALLINT, DecimalScale SMALLINT)
RETURNS: BIT
NOTES:
NULL for ValueToConvert returns True / 1
DecimalPrecision and DecimalScale are only needed if Decimal / Numeric are specified and can be
set to NULL otherwise
ConvertToDataTypes:
o Allows for one or more datatypes to be tested for possible conversion
o Accepts both datatype names as well as numeric equivalents separated by pipes |
o Is NOT case-sensitive
o Datatype values:
BIT = 1
TINYINT = 2
SMALLINT = 4
INT = 8
BIGINT = 16
DECIMAL / NUMERIC = 32
MONEY = 64
SMALLMONEY = 128
REAL = 256
FLOAT = 512
SMALLDATETIME = 1024
DATETIME = 2048
DATETIME2 = 4096
DATE = 8192
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 69 of 210
TIME = 16384
DATETIMEOFFSET = 32768
XML = 65536
UNIQUEIDENTIFIER = 131072
TIMESTAMP / ROWVERSION = 262144
EXAMPLES:
SELECT SQL#.Util_IsValidConvert('12331', 'int|SmallInt|xml', NULL, NULL) -- 1
SELECT SQL#.Util_IsValidConvert('12331', 1, NULL, NULL) -- 1
SELECT SQL#.Util_IsValidConvert('12331', 5, NULL, NULL) -- 1
SELECT SQL#.Util_IsValidConvert('12331', 4 | 8 | 16 | 32, NULL, NULL) -- 1
SELECT SQL#.Util_IsValidConvert('12312.3123123123124', 4 | 8 | 16 | 32, 5, 1) --
0
SELECT SQL#.Util_IsValidConvert('5555-12-01 12:12:12.121', 1024, 5, 1) -- 0
SELECT SQL#.Util_IsValidConvert('1922-12-01 12:12:12.121', 2048 | 32768, 5, 1) -
- 1
SELECT SQL#.Util_IsValidConvert('12312', 524288, 5, 1) -- 0
Util_IsValidPostalCode
Util_IsValidPostalCode(CountryCode NVARCHAR(4000), PostalCode NVARCHAR(4000))
RETURNS: BIT
NOTES:
This does NOT determine in any way if the PostalCode is active or has ever been used; it can only
check that it is a code that “could” be used
PostalCode is NOT case-sensitive
CountryCode is NOT case-sensitive
CountryCode is an ISO two-character Country Code (see LookUp_GetCountryInfo for more
information on ISO Country Codes)
If an unsupported CountryCode is given, a NULL is returned.
Currently only US and CA are supported Country Codes.
o US: 5 or 9 (Zip+4) digit Zipcodes; 9 digit can have dash or not
o CA: 6 character code, or 7 with a space in the middle
EXAMPLES:
SELECT SQL#.Util_IsValidPostalCode('us','55555-6794')
-- 1
SELECT SQL#.Util_IsValidPostalCode('US','555556794')
-- 1
SELECT SQL#.Util_IsValidPostalCode('us','55555+6794')
-- 0
SELECT SQL#.Util_IsValidPostalCode('ca','a1a 1a1')
-- 1
SELECT SQL#.Util_IsValidPostalCode('CA','a1a1a1')
-- 1
Util_IsValidSSN
Util_IsValidSSN(SSN NVARCHAR(4000))
RETURNS: BIT
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 70 of 210
NOTES:
This does NOT determine in any way if the SSN is active or has ever been used; it can only check
that it is a number that “could” be used
SSN can have dashes or just the numbers; it is the same either way
EXAMPLES:
SELECT SQL#.Util_IsValidSSN('123-45-6789')
-- 1
SELECT SQL#.Util_IsValidSSN('123456789')
-- 1
SELECT SQL#.Util_IsValidSSN('1234567890')
-- 0
SELECT SQL#.Util_IsValidSSN('123bob789')
-- 0
SELECT SQL#.Util_IsValidSSN('888-23-4567')
-- 0
Util_Print
Util_Print
@Source NVARCHAR(MAX),
@WordWrap BIT = 1,
@MaxLineLength SMALLINT = 4000,
@WordWrapCharactersOverride NVARCHAR(50) = NULL
PROC: Similar to the T-SQL PRINT command but takes in an NVARCHAR(MAX) and will chop the string into
4000 character segments (PRINT is limited to 4000 double-byte characters) complete with word-wrapping.
NOTES:
@Source:
o The string to send to the client program (i.e. the Messages tab in SSMS)
@WordWrap:
o Whether or not to break the current line at the most recent word-wrap character (see
@WordWrapCharactersOverride) if the line reaches the maximum length (see
@MaxLineLength)
o Default value = 1 / true
@MaxLineLength:
o The longest a line of text, not broken by a newline character, can be before continuing on the
following line
o Value of NULL, < 1, or > 4000 equate to 4000
o While the T-SQL PRINT command can do up to 8000 VARCHAR / single-byte characters, the
SQL CLR API only allows for NVARCHAR / double-byte strings.
o Default value = 4000
@WordWrapCharactersOverride:
o If not overridden, word-wrap characters are just [space] and [tab].
o If overridden, there are no default characters. Meaning, if you want a third character (e.g. a
comma as well as [space] and [tab]), then you need to set this parameter to all three. This
allows you to remove [space] and/or [tab] by not including them in this parameter.
o Setting this parameter has no effect if @WordWrap is set to 0 / False.
o Default value = NULL (this keeps the default characters of [space] and [tab])
EXAMPLES:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 71 of 210
12345
67
890 1
23456
7890
~~~~~~~~~~~~~~~~~~~
12345
67
890
12345
67890
~~~~~~~~~~~~~~~~~~~
1234
567
890 1
234
56789
0
Util_ToWords
Util_ToWords(NumericValue FLOAT)
RETURNS: NVARCHAR(4000)
NOTES:
This can be used for creating checks, much like the function in Crystal Reports.
EXAMPLES:
SELECT SQL#.Util_ToWords(91231.67)
--Returns: Ninety One Thousand, Two Hundred Thirty One and 67
SELECT SQL#.Util_ToWords(47006.6)
--Returns: Forty Seven Thousand, Six and 60
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 72 of 210
Date
Date_Age
Date_Age(StartDate DATETIME, EndDate DATETIME, LeapYearHandling NVARCHAR(4000), IncludeDays
BIT)
RETURNS: FLOAT
Determine the age assuming that StartDate is a Birth-date or Anniversary-date or some equivalent. The
assumption is used to determine how many days from the most recent occurrence of the day component and
the EndDate. Meaning, if a Birthday is 2000-05-21 and the EndDate is 2005-02-17, then the whole-value part
of the Age is 4 (since 05-21 has not been reached yet) but there are 272 days between 2004-05-21 (the most
recent occurrence of 05-21) and 2005-02-17.
NOTES:
LeapYearHandling
th
o Controls how calculations are made when the Month and Day for StartDate is February 29
(Leap Day).
o Values are NOT case-sensitive
o Valid values are:
th
28 / F / Feb = when not in a leap-year, anniversary day is observed on February 28 .
st
1 / M / March = when not in a leap-year, anniversary day is observed on March 1 .
IncludeDays:
o Whether or not to return the number of days from the most recent occurance of the Month
and Day portion of StartDate prior to EndDate.
o If set to True / 1, the number of days as the decimal component (i.e. days / 1000). The
values will be between 0 and 365. A value of 365 will occur when the StartDate is on
th th
February 29 and EndDate is set to February 28 in a Leap Year while using “28” or “F” or
“Feb” as the LeapYearHandling because the most recent occurrence of the anniversary day
th
will have occurred in a non-leap year which is then observed on February 28 but in the
th
current year (as specified in EndDate) there is a February 29 , which is 365 days later than
th
the previous February 28 .
o If set to False / 0, the number of days will not be calculated (to save time) and will always
return .000 so that you do not have to use FLOOR() if you only want the INT value.
EXAMPLES:
SELECT SQL#.Date_Age('1996-02-29', '2007-11-23', '28', 1)
-- 11.268
SELECT SQL#.Date_Age('1996-02-29', '2007-11-23', '1', 1)
-- 11.267
SELECT SQL#.Date_Age('1996-02-29', '2007-11-23', '1', 0)
-- 11
Date_BusinessDays
Date_BusinessDays(StartDate DATETIME, EndDate DATETIME, ExcludeDaysMask BIGINT)
RETURNS: INT
This function works much like the T-SQL DATEDIFF function except that it excludes a variety of non-Business
Days based on the value passed in for ExcludeDaysMask. It is possible to exclude any combination of
weekend days and various holidays from the given date-range.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 73 of 210
NOTES:
The time component of StartDate and EndDate are ignored; all are seen as having a time value of:
00:00:00.000
ExcludeDaysMask is a “bit mask” field that allows for any combination of several options to be sent as
a single INT value. Just add up the individual values for the days you want to exclude and use that
total value. The chart of combinations is shown below. In the “Selected” column only two options
(Saturday and Sunday) are selected. These two options correspond to the values of 1 and 2
respectively. In combination these two are added to come up with the total of 3 that is shown at the
bottom. If “Labor Day” was also selected, the value of 1024 would be added to the total to come up
with a new total of 1027 (1 + 2 + 1024). If all values are selected the total value will be: 33554431.
The above chart can be found online in XLS format which will automatically calculate the correct
value for you after you put an X in each row under "Selected". You can download this at:
http://www.SQLsharp.com/download/SQLsharp_Date_BusinessDays.xls
The ExcludeDaysMask field can be noted in two more readable ways:
o Using simple addition ( + ):
( 1 + 2 + 4 ) -- Saturday, Sunday, and New Year’s Day
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 74 of 210
o Using Bit-wise OR ( | ):
(1 | 2 | 4 ) -- Saturday, Sunday, and New Year’s Day
This function is independent of specific years or dates so it can find Thanksgiving in any year even
though it is not the same date between years
Unlike the DATEDIFF(DAY, StartDate, EndDate) function, Date_BusinessDays() will count ALL days
in the range whereas DATEDIFF will return 1 less than the total number of days in order to give a
“difference”. For example, when comparing the same date, DATEDIFF will return 0 while
Date_BusinessDays() will return 1 (assuming that the day isn’t excluded for some reason). This
difference is due to Date_BusinessDays() giving a true count of the number of Business Days within
the given date-range as opposed to the difference in number of days within the date-range.
Additional holidays will be added over time and can also be done by request
EXAMPLES:
SELECT DATEDIFF(DAY, '11/18/2007', '11/25/2007')
-- Sunday, Nov. 18th - Sunday, Nov. 25th
-- 7
RETURNS: DATETIME
This function works much like the T-SQL DATEADD function except that it excludes a variety of non-Business
Days based on the value passed in for ExcludeDaysMask. It is possible to exclude any combination of
weekend days and various holidays from the given date-range.
NOTES:
Please see the NOTES for Date_BusinessDays for information on ExcludeDaysMask values
See also: Date_IsBusinessDay
EXAMPLES:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 75 of 210
Date_DaysInMonth
Date_DaysInMonth(Year INT, Month INT)
RETURNS: INT
NOTES:
Takes Leap Years into account
NULL input returns NULL
EXAMPLES:
SELECT SQL#.Date_DaysInMonth(2007, 2)
-- 28
SELECT SQL#.Date_DaysInMonth(2008, 2)
-- 29
SELECT SQL#.Date_DaysInMonth(2008, 3)
-- 31
Date_DaysInMonthFromDateTime
Date_DaysInMonthFromDateTime(TheDate DATETIME)
RETURNS: INT
NOTES:
Takes Leap Years into account
NULL input returns NULL
EXAMPLES:
SELECT SQL#.Date_DaysInMonthFromDateTime('2014-02-15')
-- 28
SELECT SQL#.Date_DaysInMonthFromDateTime('2012-02-15')
-- 29
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 76 of 210
RETURNS: INT
NOTES:
Takes Leap Years into account
NULL input returns NULL
EXAMPLES:
SELECT SQL#.Date_DaysLeftInMonth('2012-02-01')
-- 28
SELECT SQL#.Date_DaysLeftInMonth('2013-02-01')
-- 27
Date_DaysLeftInYear
Date_DaysLeftInYear(TheDate DATETIME)
RETURNS: INT
NOTES:
Takes Leap Years into account
NULL input returns NULL
EXAMPLES:
SELECT SQL#.Date_DaysLeftInYear('02/20/2007')
-- 314
SELECT SQL#.Date_DaysLeftInYear('02/20/2008')
-- 315
Date_Extract
Date_Extract(DatePart NVARCHAR(4000), Date DATETIME)
RETURNS: INT
Much like the Microsoft SQL Server built-in DATEPART function, Extract returns a part of the given Date.
This is modeled after the PostgreSQL function, Extract, and includes most of the DatePart values that are
handled by the built-in DATEPART SQL Server function.
NOTES:
DatePart:
o Values are NOT case-sensitive
o Valid values are:
Millennium – 1923 = 1
Century – 1923 = 19
Decade – 1923 = 192
th
ISOYear – Each year begins on the Monday of the week containing January 4 .
Year – 2010-05-03 = 2010
DayOfYear – 2010-05-03 = 123
Quarter - 2010-05-03 = 2
Month – 2010-05-03 = 5
Week – 2010-05-03 = 19
ISOWeek / ISO_WEEK – WeekNumber can be between 1 and 53, depending on
ISOYear calculation
ISOWeekDay / ISODOW – Monday = 1, Sunday = 7
Weekday – 2010-05-03 = 2
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 77 of 210
Day – 2010-05-03 = 3
Hour – 2010-05-03 15:23:46.097 = 15
Minute – 2010-05-03 15:23:46.097 = 23
Second – 2010-05-03 15:23:46.097 = 46
Millisecond – 2010-05-03 15:23:46.097 = 97
o ISO refers to ISO 8601
o ISOWeek calculation taken from Rick McCarty:
http://personal.ecu.edu/mccartyr/ISOwdALG.txt
Will return NULL when Date is NULL
EXAMPLES:
SELECT SQL#.Date_Extract('ISOYear', '2005-01-03')
-- 2005
SELECT SQL#.Date_Extract('ISOYear', '2005-01-02')
-- 2004
SELECT SQL#.Date_Extract('ISOWeek', '2005-01-02')
-- 53
Date_Format
Date_Format(TheDate DATETIME, DateTimeFormat NVARCHAR(4000), Culture NVARCHAR(10))
RETURNS: NVARCHAR(4000)
Returns a string representing the date in the specified format and optional culture.
NOTES:
DateTimeFormat
o Standard formats: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.80).aspx
o Custom formats: http://msdn.microsoft.com/en-US/library/8kb3ddd4(v=vs.80).aspx
Culture
o Optional, use empty string (‘’) to default to “current culture”
o Available culture names: http://msdn.microsoft.com/en-
US/library/system.globalization.cultureinfo(v=vs.80).aspx
Essentially the same as the new FORMAT command in SQL Server 2012:
http://msdn.microsoft.com/en-us/library/hh213505(v=sql.110).aspx
EXAMPLES:
SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'D', '')
-- Thursday, December 03, 2009
SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'D', 'de')
-- Donnerstag, 3. Dezember 2009
SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'D', 'he')
-- 9002 דצמבר30 יום חמישי
SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'D', 'fr-fr')
-- jeudi 3 décembre 2009
SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'dd', '')
-- 03
SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'dd-MMM', '')
-- 03-Dec
SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'dd-MMM', 'he')
-- 03- דצמ
SELECT SQL#.Date_Format('2009-12-03 12:45:56.345', 'tt', 'ja-jp')
-- 午後
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 78 of 210
Date_FormatTimeSpan
Date_FormatTimeSpan(StartDate DATETIME, EndDate DATETIME, OutputFormat NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
Returns a formatted string representing the amount of time between the specified DATETIME values. This is
like DATEDIFF except with DATEDIFF you can only see the difference expressed in terms of one particular
DatePart. For example, you can see the difference between ‘1/1/2008 00:00:00.000’ and ‘1/9/2008
13:42:57.098’ in terms of minutes (12,342) only or in terms of days (8) only or in terms of hours (205) only.
However, it is sometimes useful to express that time difference as being:
NOTES:
EndDate must be greater-than-or-equal-to StartDate
OutputFormat works like “printf” in that it can contain both literals that will be returned as they are as
well as variables that will be substituted for their particular values. The variables are structured to
allow flexibility in terms of offering different text dependant on the numeric value of the TimeSpanPart
of the variable. The three options are how to deal with values that are either, 0, 1, or greater-than 1.
Meaning, it might be desired to not show anything for a value of 0 (e.g. or maybe even “no minutes”
instead of “0 minutes”). It might also be desired to show the difference between “1 minute” and “2
minutes” as opposed to always having the same text and having to show “1 minutes” or even “1
minute(s)”. The variables take the form of:
%{TimeSpanPart ;; %[width]d text for 0 ;; %[width]d text for 1 ;; %[width]d text for >1}
Valid TimeSpanParts are:
ms = milliseconds
ss = seconds (1000 milliseconds)
sm = seconds with milliseconds (ss.mmm)
mi = minutes (60 seconds)
hh = hours (60 minutes)
dd = days (24 hours)
wk = weeks (7 days)
mm = months (30.44 days)
yy = years (365.25 days)
The TimeSpanParts are NOT case-sensitive.
The %d IS case-sensitive
The %[width]d will be replaced by the appropriate number for the TimeSpanPart specified.
The optional [width] value is an INT that will left-pad the resulting time component with zeroes (0).
You do NOT have to use the %d in any of the 3 text spots. If you do not want the number show (such
as might be the case with the zero spot) then it can be left out.
There is no escape-sequence for the %d; all instances of %d will be translated to the number (e.g.
%%d will be %{number} and \%d will be \{number})
You can specify any number of TimeSpanPart variables and none are required. Meaning, the time
spans will always be in terms of days, hours, and minutes, then just specify those three and not
years, months, weeks, seconds, milliseconds, or seconds with milliseconds.
The reason for having the “sm” TimeSpanPart (Seconds With Milliseconds) is to allow for seconds
and milliseconds to be expressed with a decimal such as: ss.mmm. If a variable for seconds is used
and then a separate one for milliseconds with a literal period between them, such as:
%{ss;;%d;;%d;;%d}.{%ms;;%d;;%d;;%d} seconds
then the output might look like:
1.57 seconds
when the real value is .057 for milliseconds. The problem is that as a distinct value it cannot have
leading zeros. Instead, seconds and milliseconds can be expressed separately in the following
manner:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 79 of 210
EXAMPLES:
SELECT SQL#.Date_FormatTimeSpan('1/9/2008 13:00:00.000', '1/9/2008
13:42:57.098',
'%{wk;;;;%d week, ;;%d weeks, }%{dd;;;;%d day, ;;%d days, }%{hh;;;;%d hour, ;;%d
hours, }%{mi;;;;%d minute, ;;%d minutes, }%{sm;;;;%d second;;%d seconds}')
-- 42 minutes, 57.097 seconds
Date_FirstDayOfMonth
Date_FirstDayOfMonth(TheDate DATETIME, NewHour INT, NewMinute INT, NewSecond INT,
NewMillisecond INT)
RETURNS: DATETIME
st
Returns a full DATETIME value for the 1 of whatever month is passed in.
NOTES:
Use NewHour, NewMinute, NewSecond, and NewMillisecond to control the time component of
whatever date is returned
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 80 of 210
Maximum values are: NewHour = 23, NewMinute = 59, NewSecond = 59, and NewMillisecond = 998
Any NewMillisecond value between 995 and 998 will show in the returned value as 997; this is just
how SQL Server works
If you use set NewMillisecond to 999 then it will increase the “seconds” by 1
EXAMPLES:
DECLARE @DateVal DATETIME
SET @DateVal = '02/14/2008 17:45:32.867'
SELECT SQL#.Date_FirstDayOfMonth(@DateVal, 0, 0, 0, 0) -- first moment
-- 2008-02-01 00:00:00.000
SELECT SQL#.Date_FirstDayOfMonth(@DateVal, 23, 59, 59, 998) -- last moment
-- 2008-02-01 23:59:59.997
SELECT SQL#.Date_FirstDayOfMonth(@DateVal,
DATEPART(HOUR, @DateVal),
DATEPART(MINUTE, @DateVal),
DATEPART(SECOND, @DateVal),
DATEPART(MILLISECOND, @DateVal)
) -- keep the previous time component
-- 2008-02-01 17:45:32.867
Date_FromUNIXTime
Date_FromUNIXTime(UNIXDate FLOAT)
RETURNS: DATETIME
NOTES:
UNIX time is the number of seconds since 12:00 AM, January 1 , 1970
st
EXAMPLES:
SELECT SQL#.Date_FromUNIXTime(1195386660)
-- 2007-11-18 11:51:00.000
Date_FullDateString
Date_FullDateString(TheDate DATETIME)
RETURNS: NVARCHAR(4000)
NOTES:
Displays the given date in the format of:
{Full Day Name}, {Full Month Name} {Day}, {Year}
Does not display any time information
EXAMPLES:
SELECT SQL#.Date_FullDateString('02/20/2007 17:45:10.872')
-- Tuesday, February 20, 2007
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 81 of 210
RETURNS: NVARCHAR(4000)
NOTES:
Displays the given date in the format of:
{Full Day Name}, {Full Month Name} {Day}, {Year}
Displays the given time in the format of:
{Hour}:{Minute}:{Second} {AM / PM}
Output = { Date }{ Separator }{ Time }
EXAMPLES:
SELECT SQL#.Date_FullDateTimeString('02/20/2007 17:45:10.872', ' at ')
-- Tuesday, February 20, 2007 at 5:45:10 PM
Date_FullTimeString
Date_FullTimeString(TheDate DATETIME)
RETURNS: NVARCHAR(4000)
NOTES:
Displays the given time in the format of:
{Hour}:{Minute}:{Second} {AM / PM}
Does not display any date information
EXAMPLES:
SELECT SQL#.Date_FullTimeString('02/20/2007 17:45:10.872')
-- 5:45:10 PM
Date_GetDateTimeFromIntVals
Date_GetDateTimeFromIntVals(IntDate INT, IntTime INT)
RETURNS: DATETIME
NOTES:
IntDate should be formatted as: YYYYMMDD
IntTime should be formatted as: HHMMSS
NULL input returns NULL
See also: Date_GetIntDate
See also: Date_GetIntTime
EXAMPLES:
SELECT SQL#.Date_GetDateTimeFromIntVals(20100224, 5)
-- 2010-02-24 00:00:05.000
SELECT SQL#.Date_GetDateTimeFromIntVals(20101204, 4235)
-- 2010-12-04 00:42:35.000
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 82 of 210
Date_GetIntDate
Date_GetIntDate (TheDate DATETIME)
RETURNS: INT
NOTES:
Returned value will be formatted as: YYYYMMDD
See also: Date_GetDateTimeFromIntVals
See also: Date_GetIntTime
EXAMPLES:
SELECT SQL#.Date_GetIntDate('02/17/2010 10:34:23.3')
-- 20100217
Date_GetIntTime
Date_GetIntTime (TheDate DATETIME)
RETURNS: INT
NOTES:
Returned value will be formatted as: HHMMSS
See also: Date_GetDateTimeFromIntVals
See also: Date_GetIntDate
EXAMPLES:
SELECT SQL#.Date_GetIntTime('02/17/2010 01:34:23.3')
-- 13423
Date_IsBusinessDay
Date_IsBusinessDay(TheDate DATETIME, ExcludeDaysMask BIGINT)
RETURNS: BIT
NOTES:
See NOTES on Date_BusinessDays for an explanation of ExcludeDaysMask
This function is independent of specific years or dates so it can find Thanksgiving in any year even
though it is not the same date between years
Additional holidays will be added over time and can also be done by request
See also: Date_BusinessDaysAdd
EXAMPLES:
SELECT SQL#.Date_IsBusinessDay('2008-03-21', 131072) --Good Friday
-- 0
Date_IsDaylightSavingTime
Date_IsDaylightSavingTime (LocalDate DATETIME)
RETURNS: BIT
NOTES:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 83 of 210
Date input value is assumed to be in same TimeZone as the server running SQL Server.
NULL input returns NULL
EXAMPLES:
SELECT SQL#.Date_IsDaylightSavingTime('2013-01-01')
-- 0
SELECT SQL#.Date_IsDaylightSavingTime('2013-10-01')
-- 2
Date_IsLeapYear
Date_IsLeapYear(Year INT)
RETURNS: BIT
NOTES:
NULL input returns NULL
EXAMPLES:
SELECT SQL#.Date_IsLeapYear(2007)
-- 0
SELECT SQL#.Date_IsLeapYear(2008)
-- 1
SELECT SQL#.Date_IsLeapYear(DATEPART(YEAR, GETDATE())) -- current year = 2007
-- 0
Date_LastDayOfMonth
Date_LastDayOfMonth(TheDate DATETIME, NewHour INT, NewMinute INT, NewSecond INT,
NewMillisecond INT)
RETURNS: DATETIME
Returns a full DATETIME value for the last day of whatever month is passed in.
NOTES:
Takes Leap Years into account
Use NewHour, NewMinute, NewSecond, and NewMillisecond to control the time component of
whatever date is returned
Maximum values are: NewHour = 23, NewMinute = 59, NewSecond = 59, and NewMillisecond = 998
Any NewMillisecond value between 995 and 998 will show in the returned value as 997; this is just
how SQL Server works
If you use set NewMillisecond to 999 then it will increase the “seconds” by 1
NULL input returns NULL
EXAMPLES:
DECLARE @DateVal DATETIME
SET @DateVal = '02/14/2008 17:45:32.867'
SELECT SQL#.Date_LastDayOfMonth(@DateVal, 0, 0, 0, 0) -- first moment
-- 2008-02-29 00:00:00.000
SELECT SQL#.Date_LastDayOfMonth(@DateVal, 23, 59, 59, 998) -- last moment
-- 2008-02-29 23:59:59.997
SELECT SQL#.Date_LastDayOfMonth(@DateVal,
DATEPART(HOUR, @DateVal),
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 84 of 210
DATEPART(MINUTE, @DateVal),
DATEPART(SECOND, @DateVal),
DATEPART(MILLISECOND, @DateVal)
) -- keep the previous time component
-- 2008-02-29 17:45:32.867
Date_NewDateTime
Date_NewDateTime(Year INT, Month INT, Day INT, Hour INT, Minute INT, Second INT, Millisecond)
RETURNS: DATETIME
NOTES:
Result will be NULL if any input parameter is NULL
EXAMPLES:
SELECT SQL#.Date_NewDateTime(2000, 5, 10, 16, 2, 3, 7)
-- 2000-05-10 16:02:03.007
SELECT SQL#.Date_NewDateTime(2000, 5, null, 16, 2, 3, 7)
-- NULL
Date_NthOccurrenceOfWeekday
Date_NthOccurrenceOfWeekday(Occurrence SMALLINT, Weekday NVARCHAR(10), StartDate DATETIME)
RETURNS: DATETIME
EXAMPLES:
SELECT SQL#.Date_NthOccurrenceOfWeekday(20, 'Saturday', '1/1/2009')
-- 2009-05-16 00:00:00.000
SELECT SQL#.Date_NthOccurrenceOfWeekday(3, 'Thursday', '7/1/2009')
-- 2009-07-16 00:00:00.000
RETURNS: DATETIME
NOTES:
Input is assumed to be UTC time
Local time is based on the local timezone of the server that SQL Server is running on
NULL input returns NULL
This function is DST aware and reflects the changes that occurred in the US in 2007 (see examples)
See also Date_ToUniversalTime
EXAMPLES:
SELECT SQL#.Date_ToLocalTime('2013-10-01 17:32:12.123')
-- 2013-10-01 13:32:12.123
SELECT SQL#.Date_ToLocalTime('2013-02-01 17:32:12.123')
-- 2013-02-01 12:32:12.123
SELECT SQL#.Date_ToLocalTime('2007-10-31 20:23:45'),
SQL#.Date_ToLocalTime('2006-10-31 20:23:45')
-- 2007-10-31 16:23:45.000, 2006-10-31 15:23:45.000
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 85 of 210
RETURNS: DATETIME
NOTES:
Input is assumed to be local time
Local time is based on the local timezone of the server that SQL Server is running on
NULL input returns NULL
This function is DST aware and reflects the changes that occurred in the US in 2007 (see examples)
See also Date_ToLocalTime
EXAMPLES:
SELECT SQL#.Date_ToUniversalTime('2013-03-01 7:15:49.328')
-- 2013-03-01 12:15:49.327
SELECT SQL#.Date_ToUniversalTime('2013-10-01 7:15:49.328')
-- 2013-10-01 11:15:49.327
SELECT SQL#.Date_ToUniversalTime('2007-10-31 16:25:30.123'),
SQL#.Date_ToUniversalTime('2006-10-31 16:25:30.123')
-- 2007-10-31 20:25:30.123 2006-10-31 21:25:30.123
Date_ToUNIXTime
Date_ToUNIXTime(SQLDate DATETIME)
RETURNS: FLOAT
NOTES:
UNIX time is the number of seconds since 12:00 AM, January 1 , 1970
st
EXAMPLES:
SELECT SQL#.Date_ToUNIXTime(CONVERT(DATETIME, '2007/11/18 11:51'))
-- 1195386660
Date_Truncate
Date_Truncate(DatePart NVARCHAR(4000), Date DATETIME)
RETURNS: DATETIME
Returns the given Date but each piece (Year, Month, Day, Hour, Minute, and Second) reset to the lowest
value within the given DatePart. This is modeled after the PostgreSQL function, Trunc.
NOTES:
DatePart:
o Values are NOT case-sensitive
o Valid values are (base date for examples = 2118-08-30 14:23:21.211):
Millennium = 2000-01-01 00:00:00.000
Century = 2100-01-01 00:00:00.000
Decade = 2110-01-01 00:00:00.000
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 86 of 210
EXAMPLES:
SELECT SQL#.Date_Truncate('week', '2118-08-30 14:23:21.211')
-- 2118-08-28 00:00:00.000
SELECT SQL#.Date_Truncate('Minute', '2118-08-30 14:23:21.211')
-- 2118-08-30 14:23:00.000
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 87 of 210
Internal
The SQLsharp functions reside in the main SQL# assembly. This assembly needs a security setting of at
least EXTERNAL_ACCESS if you are using any functions that access the network. Please see
SQLsharp_SetSecurity for both how to see the current settings and how to change them. However, even if
you have a security setting of EXTERNAL_ACCESS or UNRESTRICTED, users still will not have access to
these functions without being granted permission either explicitly or via SQLsharp_GrantPermissions.
NOTES:
Requires security setting of EXTERNAL_ACCESS. You might need to use SQLsharp_SetSecurity
to change the current security setting.
An error will occir if the LicenseKey is invalid or no longer eligible for updates.
SQLsharp_GrantPermissions
SQLsharp_GrantPermissions @GrantTo NVARCHAR(4000) [ , @SQLsharpSchema NVARCHAR(4000) =
NULL ]
This is a Stored Procedure. It GRANTs Permissions for SQL# Functions and Procedures to specified user(s)
NOTES:
Will NOT grant permissions to the following: SQLsharp_Setup, SQLsharp_Update,
SQLsharp_Uninstall, SQLsharp_SetSecurity, SQLsharp_GrantPermissions
The following characters are removed: *, /, -, and ;
as there is no reason to use them and filtering them can help reduce unintended use such as SQL
Injection.
SQLsharpSchema is optional and will default to ‘SQL#’ if not set or set to NULL
SQLsharpSchema should be set to the Schema name that SQL# is installed as. By default SQL# is
installed into a Schema named SQL#.
SQLsharp_Help
SQLsharp_Help
This is a Stored Procedure. It displays list of definitions (signatures) for all SQL# Functions and Procedures
SQLsharp_IsUpdateAvailable
SQLsharp_IsUpdateAvailable
RETURNS: BIT
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 88 of 210
SQLsharp_SetSecurity
SQLsharp_SetSecurity @PermissionSet INT [ , @AssemblyName NVARCHAR(4000) ] [ ,
@SetTrustworthyIfNoUser BIT ]
This is a Stored Procedure. It sets the specified Assembly PERMISSION_SET. Also, for a setting of either 2
or 3 it will also set the DB is_trustworthy_on setting to 1 (TRUE) if currently 0 (FALSE).
NOTES:
@PermissionSet:
o 0 = Display current setting
o 1 = SAFE,
o 2 = EXTERNAL_ACCESS
o 3 = UNRESTRICTED
@AssemblyName (optional):
o If not set will default to [SQL#]
o Can be set to SQL#, SQL#.OS, SQL#.Twitterizer, SQL#.SgmlReader, SQL#.FileSystem,
SQL#.Network, SQL#.DB, or SQL#.DotNetZip
@SetTrustworthyIfNoUser (optional):
o If set to 1 will ensure that the Database setting of TRUSTWORTHY is ON if the assembly is
not owned by a login that is based on an asymmetric key AND has the appropriate
permission granted to it. A login meeting this requirement is created by the installer (as of
Version 3.0.x) but if the install is customed to not use that login then this might come in
useful.
o Default = 0
SQLsharp_Setup
SQLsharp_Setup [ @SQLsharpSchema NVARCHAR(128) ] [ , @SQLsharpAssembly NVARCHAR(128) ]
This is a Stored Procedure. It creates Functions and Procedures. It is generally not needed after the initial
install of SQL# and is called via the installation script.
NOTES:
@SQLsharpSchema (optional):
o If not set it will default to whatever @SQLsharpSchema variable towards the top of the install
script was defined as (default = SQL#)
o It should not be necessary to set this explicitly as the default value should always be correct
@SQLsharpAssembly (optional):
o If set will it only create the wrapper objects (Stored Procedures / Functions / Types /
Aggregates) for the specified assembly.
o If not set it will create the wrapper objects for all installed SQL# assemblies.
o If SQL# was installed with an assembly set to skip (i.e. setting the @InstallSQL#____
variable to 0), then it can be installed later by manually running the CREATE ASSEMBLY
command manually and then executing this procedure specifying just that assembly name.
SQLsharp_Uninstall
SQLsharp_Uninstall [ @SQLsharpAssembly NVARCHAR(128) ]
This is a Stored Procedure. It drops the SQL# Functions, Procedures, User-Defined Types, and User-
Defined Aggregates wrapper objects for the specified assembly, or all assemblies if one is not specified, and
then the assembly itself, or all assemblies if one is not specified.
NOTES:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 89 of 210
@SQLsharpAssembly (optional):
o If set it will only uninstall the wrapper objects (Stored Procedures / Functions / Types /
Aggregates) for the specified assembly and the assembly itself.
o If not set it will uninstall:
the wrapper objects for all installed SQL# assemblies
all installed SQL# assemblies
the SQL# schema (if no other objects are left in it after the above items have been
removed)
This proc will check for dependent assemblies and, if found, will return an error with the name(s) of
those assemblies.
SQLsharp_Version
SQLsharp_Version()
RETURNS: NVARCHAR(4000)
SQLsharp_WebSite
SQLsharp_WebSite()
Displays the location (URL) of the SQL# website. Just in case you lose all information including this
document ;-).
RETURNS: NVARCHAR(4000)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 90 of 210
If you use any of the functions that access the file system, then these assemblies will need a security setting
of EXTERNAL_ACCESS (Level 2). You can set this by executing the following query:
If you do not want to have these assemblies in your system at all, you can do either of the following:
Do not install the SQL#.FileSystem and/or SQL#.DotNetZip assemblies by setting the
@InstallSQL#FileSystem and/or @InstallSQL#DotNetZip variables (towards the top of the
script) to 0 before installing
Uninstall either or both of the assemblies by running:
EXEC [SQL#].[SQLsharp_Uninstall] N'SQL#.FileSystem'
EXEC [SQL#].[SQLsharp_Uninstall] N'SQL#.DotNetZip'
Please note that when accessing the file system, the Operating System user account that will be used is the
one that is currently running (i.e. “Log On as”) the main SQL Server process (it might be Local System
Account or an account created specifically for SQL Server).
The list of Encoding names that can be used are as follows (those ending in “...NoBOM” do not write out the
Byte Order Mark / BOM when creating files; multiple entries on the same line are the same base encoding):
ASCII
UTF7
UTF8 / UTF8NoBOM
UTF16 / UTF16Le / Unicode
UTF16NoBOM / UTF16LeNoBOM / UnicodeNoBOM
UTF16Be / BigEndianUnicode
UTF16BeNoBOM / BigEndianUnicodeNoBOM
UTF32 / UTF32Le
UTF32NoBOM / UTF32LeNoBOM
UTF32Be, UTF32BeNoBOM
The list of possible integer values that can be used can be found here ( https://msdn.microsoft.com/en-
us/library/system.text.encoding.aspx#Anchor_5 ). Values can be from the "Code Page" column or the "Name"
column.
File_ChangeEncoding
File_ChangeEncoding(FilePath NVARCHAR(4000), CurrentEncoding NVARCHAR(30), FilePathNew
NVARCHAR(4000), NewEncoding NVARCHAR(30), OverwriteExistingFile BIT, RemoveOriginalFile BIT)
RETURNS: NVARCHAR(4000)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 91 of 210
NOTES:
FilePath cannot be NULL or empty string
IF FilePathNew IS NULL or is an empty string, then the file specified by FilePath will be over-written
with the new encoding
Please see the Note on Encoding Parameters for possible values for both “Encoding” parameters.
SourceEncoding and NewEncoding is NOT case-sensitive
IF file specified by FilePathNew already exists, an error will be thrown unless OverwriteExistingFile is
set to 1 (true)
OverwriteExistingFile must be set to 1 (true) IF NewFilePath IS NULL or is empty string
RemoveOriginalFile must be set to 0 (false) IF NewFilePath IS NULL or is empty string
The return value is an empty string upon success or an error message
EXAMPLES:
SELECT SQL#.File_ChangeEncoding('C:\SQL\exported_unicode_file.sql', 'utf8', '',
'Ansi', 1, 0);
-- simply update the file to ANSI / ASCII format
SELECT SQL#.File_ChangeEncoding('C:\some_file.txt', '1255',
'C:\new_path\some_file.txt', 'utf8', 1, 1)
-- convert the file and save in a new location, removing the original
File_Copy
File_Copy(SourceFilePath NVARCHAR(4000), DestinationFilePath NVARCHAR(4000), OverWrite BIT)
RETURNS: NVARCHAR(4000)
NOTES:
SourceFilePath and DestinationFilePath cannot be empty string or NULL
SourceFilePath and DestinationFilePath must be absolute paths (including the drive letter or UNC
paths) and not relative ones
If an error occurs it will be returned as the NVARCHAR(4000) else an empty string is returned
If there is already a file at the DestinationFilePath of the same name as the SourceFilePath filename
then it will either throw an error (if OverWrite is set to False / 0) or it will over-write the file (if
OverWrite is set to True / 1)
If the directory / folder portion of DestinationFilePath does not exist, it will NOT be created and an
error will be thrown
EXAMPLES:
SELECT SQL#.File_CreateDirectory('C:\SQL#Test\Sub1\Sub2')
SELECT SQL#.File_WriteFile('C:\SQL#Test\Sub1\test.txt', 'Hello', 0, '')
SELECT SQL#.File_Copy('C:\SQL#Test\Sub1\test.txt', 'C:\SQL#Test\Sub3\test.txt',
0)
-- error caused since C:\SQL#TestFolder\Sub3 does not exist
SELECT SQL#.File_Copy('C:\SQL#Test\Sub1\test.txt',
'C:\SQL#Test\Sub1\Sub2\test.txt', 0)
-- copies file to Sub2 directory
SELECT SQL#.File_Copy('C:\SQL#Test\Sub1\test.txt',
'C:\SQL#Test\Sub1\Sub2\test.txt', 0)
-- error since file exists from previous command and OverWrite is set to 0
SELECT SQL#.File_Copy('C:\SQL#Test\Sub1\test.txt',
'C:\SQL#Test\Sub1\Sub2\test.txt', 1)
-- now it works since OverWrite is set to 1
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 92 of 210
File_CopyMultiple
File_CopyMultiple(StartingDirectory NVARCHAR(4000), Recursive BIT, DirectoryNamePattern
NVARCHAR(4000), FileNamePattern NVARCHAR(4000), DestinationDirectory NVARCHAR(4000),
OverWrite BIT)
Copies any files matching both the DirectoryNamePattern and FileNamePattern to the DestinationDirectory.
Unlike File_Copy, File_CopyMultiple will create any directories in the DestinationDirectory that do not already
exist rather than throwing an error.
NOTES:
StartingDirectory cannot be empty string or NULL
StartingDirectory must be an absolute path (including the drive letter or UNC path) and not a relative
one
DirectoryNamePattern and FileNamePattern are full Regular Expressions and if left empty will match
everything
DestinationDirectory cannot be empty string or NULL
DestinationDirectory must be an absolute path (including the drive letter or UNC path) and not a
relative one
Any Exceptions / Errors will be reported per file and will not stop the rest of the operation
An error will occur if there is a file of the same name at the Destination location AND OverWrite is set
to False / 0
If Recursive is set to True / 1 then any directories that contain files to be copied to the
DestinationDirectory will be created at the Destination in order to preserve the Source’s directory
structure
In the returned table:
o OriginalLocation and NewLocation are just the directories and do not include the Name of the
file as it will not change when copied. If you need to change file names at the Destination
then you need to copy them individually using File_Copy
o Operation is always “COPY”
In the returned table, Level will always be 0 when Recursive is set to False / 0 and will start with 1 as
the base directory when Recursive is set to True / 1
EXAMPLES:
SELECT * FROM SQL#.File_CopyMultiple('C:\DBFiles', 0, '', '\.bak$',
'C:\DBBackUps', 1)
-- copy all .bak files (non-recursively) to a backup location,
-- do not overwrite
SELECT * FROM SQL#.File_CopyMultiple('C:\INetPub\WWWRoot', 1, 'images',
'(\.gif|\.jpg)$', 'C:\WebSiteBackUps', 1)
-- copy GIF and JPG files from websites directories (recursively)
-- to backup location, overwritting existing files
File_CreateDirectory
File_CreateDirectory(FilePath NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
NOTES:
FilePath cannot be NULL or an empty string
Will create all Directories in the path if they do not exist
Nothing (empty string) is returned if successful or the error is returned
An error will occur if the drive or UNC share path cannot be found
EXAMPLES:
SELECT SQL#.File_CreateDirectory('C:\doesnt_exist\sub1')
-- creates C:\doesnt_exist\ and then C:\doesnt_exist\sub1\
File_CreateTempFile
File_CreateTempFile
RETURNS: NVARCHAR(4000)
Creates a uniquely-named, empty file and returns the full path to it.
NOTES:
File is created in the temp directory associated with the user/account that the SQL Server process
logs on as.
EXAMPLES:
DECLARE @Path NVARCHAR(1000)
SET @Path = SQL#.File_CreateTempFile()
File_CurrentEncoding
File_CurrentEncoding(FilePath NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
NOTES:
FilePath cannot be NULL or an empty string
Possible return values are:
o Western European (Windows)
o Unicode [implied Little-Endian]
o Unicode (Big-Endian)
o Unicode (UTF-8)
o Unicode (UTF-32) [implied Little-Endian]
EXAMPLES:
SELECT SQL#.File_ChangeEncoding('c:\one.txt', 'c:\two.txt', 'utf32', 1, 0)
SELECT SQL#.File_CurrentEncoding('C:\two.txt')
-- Unicode (UTF-32)
File_Decrypt
File_Decrypt(FilePath NVARCHAR(4000))
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 94 of 210
Decrypts a file that has been: a) encrypted by the same user account that is trying to Decrypt it, and b)
encrypted by either File_Encrypt or anything that calls the general Windows File System Encrypt function
(such as right-clicking on a file, going to Properties | Advanced, and checking “Encypt Conents to Secure
Data”)
RETURNS: NVARCHAR(4000)
NOTES:
FilePath cannot be NULL or an empty string
Nothing (empty string) is returned if successful or the error is returned
Only the OS user account that Encrypted the file can Decrypt it, in the case of running this within SQL
Server it will be the account that SQL Server runs under
See File_Encrypt for more details
EXAMPLES:
SELECT SQL#.File_Decrypt('C:\SQL#Test\test.txt')
File_Delete
File_Delete(FilePath NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
NOTES:
FilePath cannot be NULL or an empty string
Nothing (empty string) is returned if successful or the error is returned
Cannot delete an entire directory; for that use File_DeleteDirectory
EXAMPLES:
SELECT SQL#.File_Delete('C:\SQL#Test\test.txt')
File_DeleteDirectory
File_DeleteDirectory(FilePath NVARCHAR(4000), Recursive BIT)
RETURNS: NVARCHAR(4000)
NOTES:
FilePath cannot be NULL or an empty string
Nothing (empty string) is returned if successful or the error is returned
If Recursive is set to 1 / True, then it will delete the entire directory structure starting with FilePath
(like “rm -r” in UNIX)
If Recursive is set to 0 / False, then the directory must be empty (no files or subdirectories) or else an
error will occur
FilePath cannot be a file
EXAMPLES:
SELECT SQL#.File_DeleteDirectory('C:\SQL#Test\Sub1\Sub2', 0)
-- causes an error: The directory is not empty.
SELECT SQL#.File_DeleteDirectory('C:\SQL#Test\Sub1\Sub2', 1)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 95 of 210
-- all gone!
File_DeleteMultiple
File_DeleteMultiple(StartingDirectory NVARCHAR(4000), Recursive BIT, DirectoryNamePattern
NVARCHAR(4000), FileNamePattern NVARCHAR(4000))
Deletes any files matching both the DirectoryNamePattern and FileNamePattern to the DestinationDirectory.
DeleteMultiple will only delete files—not directories—and any directories left empty by deleting all of their files
will still remain.
NOTES:
StartingDirectory cannot be empty string or NULL
StartingDirectory must be an absolute path (including the drive letter or UNC path) and not a relative
one
DirectoryNamePattern and FileNamePattern are full Regular Expressions and if left empty will match
everything
Any Exceptions / Errors will be reported per file and will not stop the rest of the operation
If Recursive is set to True / 1 then any directories below StartingDirectory that contain files to be
deleted will be traversed
In the returned table:
o OriginalLocation is just the directory and does not include the Name of the file
o NewLocation is always NULL since it is not applicable
o Operation is always “DELETE”
In the returned table, Level will always be 0 when Recursive is set to False / 0 and will start with 1 as
the base directory when Recursive is set to True / 1
EXAMPLES:
SELECT * FROM SQL#.File_DeleteMultiple('C:\DBFiles', 0, '', '\.bak$')
-- delete all .bak files (non-recursively) in C:\DBFiles,
SELECT * FROM SQL#.File_DeleteMultiple('C:\INetPub\WWWRoot', 1, 'images',
'(\.gif|\.jpg)$')
-- delete GIF and JPG files from websites directories (recursively)
File_Encrypt
File_Encrypt(FilePath NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
Encrypts files so that only the OS user account that Encrypted it can read it. The file is readable while
Encrypted, but cannot be read by any OS account other than the one that Encrypted it unless it is Decrypted
by the OS account that Encrypted it.
NOTES:
FilePath cannot be NULL or an empty string
Nothing (empty string) is returned if successful or the error is returned
Only the OS user account that Encrypts the file can Decrypt it, in the case of running this within SQL
Server it will be the account that SQL Server runs under
See File_Decrypt for more details
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 96 of 210
Encrypted does not mean unreadable; the file is still fully readable but ONLY by the OS user account
that Encrypted it
EXAMPLES:
SELECT SQL#.File_Encrypt('C:\SQL#Test\test.txt')
File_GetDirectoryListing
File_GetDirectoryListing(StartingDirectory NVARCHAR(4000), Recursive BIT, DirectoryNamePattern
NVARCHAR(4000), FileNamePattern NVARCHAR(4000), @IncludeSecurityInfo BIT)
NOTES:
If the “Log On As” account for the SQLServer service does not have permissions to enter a directory,
that error will be noted in the ErrorMessage field.
Retrieving the security info fields has a definite negative impact on performance. Please set
@IncludeSecurityInfo to 0 unless you need that information.
The “SecurityDescriptor” field is the NTFS ACL information, in SDDL notation, minus the Owner and
Group, both of which are broken out into their own pairs of fields for “SID” and “Name”.
The “OwnerName” and “GroupName” fields always return NULL, and will do so until they can be
cached (that lookup is an even larger performance hit). Until then, the SIDs can be translated into
names either by using the new OS_TranslateSddlSidToName function, or by using
“SUSER_SNAME(SQL#.Convert_SddlSidToBinary(OwnerSID))”.
EXAMPLES:
SELECT * FROM SQL#.File_GetDirectoryListing(N'C:\SQL#Test\', 0, '', '', 0)
-- List all files and directories in C:\SQL#Test but not recursively
SELECT * FROM SQL#.File_GetDirectoryListing(N'C:\SQL#Test\', 1, '', '\.htm', 0)
-- List files with .htm* extension, recursively starting in C:\SQL#Test
SELECT * FROM SQL#.File_GetDirectoryListing(N'C:\INetPub\WWWRoot\', 1,
N'^images$', N'(\.gif|\.jpg)', 0)
-- List files with .gif or .jpg extensions, recursively starting in
-- C:\INetPub\WWWRoot\ and in folders named "images"
SELECT * FROM SQL#.File_GetDirectoryListing(N'C:\', 0, N'', N'', 1)
-- get listing from root directory; include security info
SELECT * FROM SQL#.File_GetDirectoryListing(N'\\Server\Share\', 0, N'', N'', 0)
-- get listing from a UNC path
SELECT SUM([Length]) FROM SQL#.File_GetDirectoryListing(N'C:\Windows\Temp', 1,
N'', N'', 0) -- get total size (in bytes) of C:\Windows\Temp directory
File_GetDirectoryName
File_GetDirectoryName(FilePath NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
EXAMPLES:
SELECT SQL#.File_GetDirectoryName('C:\Test\Path\FileName.ext')
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 97 of 210
-- C:\Test\Path
SELECT SQL#.File_GetDirectoryName('\\SERVER\ShareName\Path\FileName.ext')
-- \\SERVER\ShareName\Path
File_GetDriveInfo
File_GetDriveInfo(DriveName NVARCHAR(4000))
NOTES:
DriveName is NOT case-sensitive
DriveName can be either a Drive Letter (e.g. ‘C’, ‘C:’, or ‘C:\’) or empty string ‘’ or NULL
IF DriveName is to be an empty string or NULL, then a security setting of 3 (UNRESTRICTED) is
required; see SQLsharp_SetSecurity for more details
IF DriveName is a drive letter, then a security setting of 2 (EXTERNAL_ACCESS) will work
In the result set:
o Format can be: NTFS, CDFS, FAT32, etc
o DriveType can be: CDRom, Fixed, Unknown, Network, NoRootDirectory, Ram, Removable
EXAMPLES:
SELECT * FROM SQL#.File_GetDriveInfo('')
/*
C:\ NTFS Fixed C:\ 120023252992 55667834880 64355418112 64355418112
D:\ music CDFS CDRom D:\ 650801152 650801152 0 0
*/
SELECT * FROM SQL#.File_GetDriveInfo('c')
/*
C:\ NTFS Fixed C:\ 120023252992 55667834880 64355418112 64355418112
*/
File_GetFile
File_GetFile(FilePath NVARCHAR(4000), SplitLines BIT, FileEncoding NVARCHAR(30))
NOTES:
If FilePath does not exist, LineNum / ContentLength / LineLength will all be -1, ContentEncoding will
be NULL, and the Content field will be the system error message.
If SplitLines = 0
o One row is returned.
o LineNum = the total number of lines.
o ContentLength = total characters in the file (including newlines and/or returns).
o LineLength = ContentLength.
o Entire file is loaded into memory so that it can be returned without splitting.
If SplitLines = 1
o One row per line of the file is returned.
o LineNum = actual line number of the file.
o ContentLength = cumulative number of characters (excluding newlines / returns) read so far,
inclusive of the current line.
o LineLength = the number of characters (excluding newlines / returns) of the current line.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 98 of 210
o Stream rows from file to SQL Server; only 1 row of the file in memory at a time.
FileEncoding
o Please see the Note on Encoding Parameters for possible values.
EXAMPLES:
SELECT * FROM SQL#.File_GetFile('C:\nofile', 0)
-- -1 NULL -1 Could not find file 'C:\nofile'. -1
SELECT * FROM SQL#.File_GetFile('C:\Boot.ini', 0)
-- 6 utf-8 211 [boot loader] timeout=30... 211
SELECT * FROM SQL#.File_GetFile('C:\Boot.ini', 1)
/*
1 utf-8 13 [boot loader]
2 utf-8 10 timeout=30
3 utf-8 51 default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS
4 utf-8 19 [operating systems]
...
*/
File_GetFileBinary
File_GetFileBinary(FilePath NVARCHAR(4000))
RETURNS: VARBINARY(MAX)
Reads the contents of a binary file. File_GetFileBinary can read both binary and text files whereas
File_GetFile can only read text files.
NOTES:
FilePath cannot be NULL or an empty string
This is a scalar-valued function unlike File_GetFile which is a table-valued function
EXAMPLES:
SELECT SQL#.File_GetFileBinary('C:\Temp\manual.pdf')
File_GetFileInfo
File_GetFileInfo(FilePath NVARCHAR(4000))
EXAMPLES:
SELECT * FROM SQL#.File_GetFileInfo('c:\boot.ini')
File_GetFileName
File_GetFileName(FilePath NVARCHAR(4000), RemoveExtension BIT)
RETURNS: NVARCHAR(4000)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 99 of 210
EXAMPLES:
SELECT SQL#.File_GetFileName('C:\Test\Path\FileName.ext', 0)
-- FileName.ext
SELECT SQL#.File_GetFileName('C:\Test\Path\FileName.ext', 1)
-- FileName
SELECT SQL#.File_GetFileName('\\SERVER\ShareName\Path\FileName.ext', 0)
-- FileName.ext
SELECT SQL#.File_GetFileName('\\SERVER\ShareName\Path\FileName.ext', 1)
-- FileName
SELECT SQL#.File_GetFileName('C:\Test\Path\FileName.ext.zip', 1)
-- FileName.ext
File_GetLineCount
File_GetLineCount(FilePath NVARCHAR(4000), TrapErrorsInline BIT)
RETURNS: INT
NOTES:
Does not load entire file into memory; only one line at a time is loaded. Max memory used is longest
line of the file.
TrapErrorsInline:
o 0 / False = if an error is encountered, fail with an exception
o 1 / True = if an error is encountered, return value is an error code denoted by a negative
value (see below)
Error code return values:
o Only returned when TrapErrorsInline = 1
o -1 = File Not Found
o -2 = Directory Not Found
o -3 = Drive Not Found
o -4 = File Load Exception
o -5 = Path Too Long
o -6 = IO Exception
o -7 = Unauthorized Access
o -99 = Other
EXAMPLES:
SELECT SQL#.File_GetLineCount(N'C:\Windows\system.ini', 0);
-- 13
SELECT SQL#.File_GetLineCount(N'C:\pagefile.sys', 0);
-- System.IO.IOException
SELECT SQL#.File_GetLineCount(N'C:\pagefile.sys', 1);
-- -6
File_GetRandomFileName
File_GetRandomFileName()
RETURNS: NVARCHAR(4000)
NOTES:
Return value is a cryptographically strong, random string that can be used as either a folder name or
a file name
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 100 of 210
EXAMPLES:
SELECT SQL#.File_GetRandomFileName()
-- nfuiogeq.vt2
-- w5wkauub.bzz
File_GetRootDirectory
File_GetRootDirectory(FilePath NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
Returns just the Root Directory or UNC Server and Share Name.
EXAMPLES:
SELECT SQL#.File_GetRootDirectory('C:\Test\Path\FileName.ext')
-- C:\
SELECT SQL#.File_GetRootDirectory('\\SERVER\ShareName\Path\FileName.ext')
-- \\SERVER\ShareName
File_GetTempPath
File_GetTempPath()
RETURNS: NVARCHAR(4000)
NOTES:
Returns the path/directory of the system’s Temp directory
Can be used in conjunction with File_GetRandomFileName() for creating temporary files that should
have unique and non-predictable names.
EXAMPLES:
SELECT SQL#.File_GetTempPath()
-- C:\WINDOWS\TEMP\
File_GUnzip
File_GUnzip(FilePath NVARCHAR(4000), OverwriteExistingFile BIT, RemoveOriginalFile BIT)
RETURNS: NVARCHAR(4000)
NOTES:
FilePath cannot be NULL or empty string
FilePath filename must end in “.gz” else an error will be thrown
IF filename of FilePath without the “.gz” extension already exists, an error will be thrown unless
OverwriteExistingFile is set to 1 (true)
Return value is empty string upon success or any errors generated
This function can handle files of any size as it only operates on 8k at a time as opposed to
Util_GUnzip which has to read the entire VARBINARY(MAX) into memory first.
This function resides in the SQL#.DotNetZip assembly, not in SQL#.FileSystem.
EXAMPLES:
SELECT SQL#.File_GUnzip('C:\Manual.PDF.gz', 1, 1)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 101 of 210
File_GZip
File_GZip(@FilePath NVARCHAR(4000), OverwriteExistingFile BIT, RemoveOriginalFile BIT)
RETURNS: NVARCHAR(4000)
NOTES:
FilePath cannot be NULL or empty string
IF filename of FilePath with the “.gz” extension already exists, an error will be thrown unless
OverwriteExistingFile is set to 1 (true)
Return value is empty string upon success or any errors generated
This function can handle files of any size as it only operates on 8k at a time as opposed to Util_GZip
which has to read the entire VARBINARY(MAX) into memory first.
This function resides in the SQL#.DotNetZip assembly, not in SQL#.FileSystem.
EXAMPLES:
SELECT SQL#.File_GZip('C:\Manual.PDF', 1, 1)
File_Move
File_Move(SourceFilePath NVARCHAR(4000), DestinationFilePath NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
NOTES:
SourceFilePath and DestinationFilePath cannot be empty string or NULL
SourceFilePath can be either a full filename or just a directory
If SourceFilePath is a filename, then DestinationPath must also be a filename
Use File_Move to rename a file by keeping it in the same directory but specifying a new name in the
DestinationFilePath
If SourceFilePath is a directory, then DestinationFilePath will be taken as a directory name
SourceFilePath and DestinationFilePath must be absolute paths (including the drive letter or UNC
paths) and not relative ones
If an error occurs it will be returned as the NVARCHAR(4000) else an empty string is returned
If there is already a file at the DestinationFilePath of the same name as the SourceFilePath filename
then it will throw an error
If the directory / folder portion of DestinationFilePath does not exist, it will NOT be created and an
error will be thrown
EXAMPLES:
SELECT SQL#.File_Move('C:\SQL#Test\test.txt', 'C:\SQL#Test\Sub1\t2.txt')
-- move the test.txt file to another directory with a new name
SELECT SQL#.File_Move('C:\SQL#Test\test.txt', 'C:\SQL#Test\t2.txt')
-- rename the test.txt file to t2.txt
SELECT SQL#.File_Move('C:\SQL#Test\Sub1', 'C:\Temp')
-- move the C:\SQL#Test\Sub1 directory structure to C:\Temp
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 102 of 210
File_MoveMultiple
File_MoveMultiple(StartingDirectory NVARCHAR(4000), Recursive BIT, DirectoryNamePattern
NVARCHAR(4000), FileNamePattern NVARCHAR(4000), DestinationDirectory NVARCHAR(4000))
NOTES:
StartingDirectory cannot be empty string or NULL
StartingDirectory must be an absolute path (including the drive letter or UNC path) and not a relative
one
DirectoryNamePattern and FileNamePattern are full Regular Expressions and if left empty will match
everything
DestinationDirectory cannot be empty string or NULL
DestinationDirectory must be an absolute path (including the drive letter or UNC path) and not a
relative one
Any Exceptions / Errors will be reported per file and will not stop the rest of the operation
An error will occur if there is a file of the same name at the Destination location
If Recursive is set to True / 1 then any directories that contain files to be copied to the
DestinationDirectory will be created at the Destination in order to preserve the Source’s directory
structure
In the returned table:
o OriginalLocation and NewLocation are just the directories and do not include the Name of the
file as it will not change when moved. If you need to change file names at the Destination
then you need to move them individually using File_Move
o Operation is always “MOVE”
In the returned table, Level will always be 0 when Recursive is set to False / 0 and will start with 1 as
the base directory when Recursive is set to True / 1
EXAMPLES:
SELECT * FROM SQL#.File_MoveMultiple('C:\SQL#Test', 0, '', '\.txt$', 'C:\Temp')
-- move .txt files from C:\SQL#Test (but not its subfolders) to C:\Temp
SELECT * FROM SQL#.File_MoveMultiple('C:\INetPub', 1, 'images', '', 'C:\Temp')
-- move all files from folders named "images" within C:\INetPub to C:\Temp
File_PathExists
File_PathExists(InputPath NVARCHAR(4000))
RETURNS: INT
NOTES:
Return values: 0 = Does Not Exist; 1 = Is A Directory; 2 = Is A File
This can be used in conjunction with File_WriteFile() to determine if the file already exists as
File_WriteFile() will over-write an existing file as opposed to throwing an error.
EXAMPLES:
SELECT SQL#.File_PathExists('C:\no_path')
-- 0
SELECT SQL#.File_PathExists('C:\')
-- 1
SELECT SQL#.File_PathExists('C:\Boot.ini')
-- 2
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 103 of 210
File_SplitIntoFields
File_SplitIntoFields @FilePath NVARCHAR(4000), @RegExDelimiter NVARCHAR(4000) [, @RowsToSkip
INT] [, @ColumnNames NVARCHAR(4000)] [, @FileEncoding NVARCHAR(20)] [, @DataTypes
NVARCHAR(4000)]
PROC: Result set is each row of file specified by @FilePath broken into fields based on @RegExDelimiter
NOTES:
@FilePath:
o cannot be NULL or empty string
o IF @FilePath does not exist an error will be thrown
@RegExDelimiter is a full Regular Expression (See RegEx section)
@RowsToSkip:
o Optional parameter
o Default = 0
o Use = 1 to ignore header row
@ColumnNames:
o Optional parameter
o Comma-separated list of values that will be used to name the columns of the result set
o Extra spaces around each name will be trimmed
o If more fields are in the data than specified in ColumnNames then additional fields will be
named as FieldN where N is the field number
o If more fields are specified in ColumnNames than in the first row of the result set then extra
Column Names will be ignored
o If not set or set to NULL then all field names will be FieldN where N is the field number
starting with 1
@FileEncoding:
o Optional parameter
o Value is NOT case-sensitive
o Value can be:
ASCII
UNICODE [implied Little Endian]
UTF8
UTF7
UnicodeBigEndian
UTF32 [implied Little Endian]
Any other value, including NULL, will select your server’s system default
@DataTypes:
o Optional parameter
o Value is NOT case-sensitive
o Comma-separated list of values that will be used to specify the datatype of the columns of the
result set
o If more fields are in the data than specified in DataTypes then additional fields will be set to
NVARCHAR(MAX)
o If more fields are specified in DataTypes than in the first row of the result set then extra
values will be ignored
o If not set or set to NULL then all field datatypes will be set to NVARCHAR(MAX)
o Empty value in source data will return empty string for (N)(VAR)CHAR / XML datatypes, 0x00
for (VAR)BINARY, and NULL for number / date datatypes.
o Currently, the TIME and DATETIMEOFFSET datatypes do not work properly.
Number of fields returned in result set is based on first row of data returned (meaning, if
@RowsToSkip = 1 then the first row of data is Row 2)
After number of fields to return is set, rows with more fields will have the additional fields ignored
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 104 of 210
After number of fields to return is set, rows with fewer fields will return empty strings for the missing
fields
See also: String_SplitIntoFields and INET_SplitIntoFields
EXAMPLES:
INSERT INTO dbo.ImportTable (ProductNo, ProductName, SKU, Qty)
EXEC SQL#.File_SplitIntoFields 'C:\test.txt', '\t', 1
-- this assumes that the "test.txt" file is tab-delimited, has
-- 4 columns, and that the first row contains the column names
File_Touch
File_Touch(FilePath NVARCHAR(4000), WhichTime NVARCHAR(20), NewAbsoluteTime DATETIME,
NewRelativeTime BIGINT, RelativeFilePath NVARCHAR(4000), SkipFileCreation BIT)
RETURNS: NVARCHAR(4000)
NOTES:
WhichTime:
o Values are NOT case-sensitive
o Values are:
“Both” or empty string ‘’ = Update both Last Access and Last Write times
“Access” = only update the Last Access time
“Write” = only update the Last Write time
NewRelativeTime can be used to modify, in MilliSeconds, either the current system time or the time of
the file specified by RelativeFilePath
NewRelativeTime can be positive or negative
RelativeFilePath points to an optional file to get the Last Access and/or Last Write time(s) from
SkipFileCreation, if set to 1 / true, will NOT create a file that does not already exist (the default
behavior of “touch” is to create a file that does not exist) and will return a message of “File does not
exist” but will not error
If NewAbsoluteTime is specified, both NewRelativeTime and RelativeFilePath must be NULL
If NewAbsoluteTime is NULL, NewRelativeTime and/or RelativeFilePath can be specified
If both NewAbsoluteTime and RelativeFilePath are NULL then time used is the current system time
EXAMPLES:
SELECT SQL#.File_Touch('C:\Test1.txt', 'Both', NULL, NULL, NULL, 1)
-- File does not exist
SELECT SQL#.File_Touch('C:\Test1.txt', 'Both', NULL, NULL, NULL, 0)
-- {this mirrors the default behavior of the "touch" command}
SELECT SQL#.File_Touch('C:\Test1.txt', '', '12/12/2001', NULL, NULL, 0)
SELECT SQL#.File_Touch('C:\Test2.txt', 'Write', NULL, NULL, 'C:\Test1.txt', 0)
SELECT SQL#.File_Touch('C:\Test2.txt', 'Both', NULL, 300000, 'C:\Test1.txt', 0)
SELECT SQL#.File_Touch('C:\Test3.txt', 'Both', NULL, -600000, NULL, 0)
File_WriteFile
File_WriteFile(FilePath NVARCHAR(4000), FileData NVARCHAR(MAX), AppendData BIT, FileEncoding
NVARCHAR(20))
RETURNS: NVARCHAR(4000)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 105 of 210
NOTES:
FilePath must be an existing directory/folder but the filename does not need to already exist (e.g.
C:\ExistingDirectory\NewFileName.txt)
AppendData = 1 will append to existing file; AppendData = 0 will overwrite an existing file
FileEncoding
o Only applies if exporting to a file
o Value is NOT case-sensitive
o Value can be:
ASCII
UNICODE [implied Little Endian]
UTF8
UTF7
UnicodeBigEndian
UTF32 [implied Little Endian]
Any other value, including NULL, will select your server’s system default
Return value is empty string '' for Success OR error message
Since this command will always over-write an existing file (or append to it) but not throw an error that
the file already exists, if you need to protect an already existing file then use File_PathExists() first
before attempting to write the file.
EXAMPLES:
CREATE TABLE #TempCLR (CLRFunction SYSNAME)
INSERT INTO #TempCLR (CLRFunction)
SELECT SPECIFIC_NAME
FROM INFORMATION_SCHEMA.ROUTINES
File_WriteFileBinary
File_WriteFileBinary(FilePath NVARCHAR(4000), FileData VARBINARY(MAX), FileMode NVARCHAR(20),
FileEncoding NVARCHAR(20))
RETURNS: NVARCHAR(4000)
NOTES:
FilePath cannot be NULL or an empty string
FileMode is NOT case-sensitive
FileMode = Create (File created if it doesn't exist or over-written if it does exist); CreateNew (Error
throw if file already exists); Append (File created if it doesn't exist or appended to if it does exist)
FileEncoding
o Only applies if exporting to a file
o Value is NOT case-sensitive
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 106 of 210
EXAMPLES:
SELECT SQL#.File_WriteFileBinary('C:\SQL#Test\test.txt', 0x48656C6C6F,
'CreateNew', '')
-- creates the file
SELECT * FROM SQL#.File_GetFile('c:\sql#Test\test.txt', 0)
-- LineNum ContentEncoding ContentLength Content
-- 1 utf-8 5 Hello
SELECT SQL#.File_WriteFileBinary('C:\SQL#Test\test.txt', 0x48656C6C6F,
'CreateNew', '')
-- error since it already exists; could use "Create" instead
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 107 of 210
Database
The Database functions reside in the SQL#.DB assembly. The following assemblies need to be installed in
order to use the DB functions: SQL#.Network.
If you use any of the functions that access the file system or network, then this assembly will need a security
setting of EXTERNAL_ACCESS (2). You can set this by executing the following query:
If you do not want to have this assembly in your system at all, you can do either of the following:
Do not install the SQL#.DB assembly by setting the @InstallSQL#DB variable (towards the top of
the script) to 0 before installing
Uninstall the assembly by running:
EXEC [SQL#].[SQLsharp_Uninstall] N'SQL#.DB'
Please note that when accessing the file system, the Operating System user account that will be used is the
service account (i.e. “log on as”) that is currently running the main “SQL Server (instance_name)” process
(instance_name = MSSQLSERVER service for a “default” instance, or something else for a named instance).
The account might be Local System Account or an account created specifically for SQL Server.
DB_BulkCopy
DB_BulkCopy [ @SourceType NVARCHAR(4000) = NULL, ]
[ @SourceConnection NVARCHAR(4000) = NULL, ]
@SourceQuery NVARCHAR(4000),
[ @DestinationConnection NVARCHAR(4000) = NULL, ]
@DestinationTableName NVARCHAR(4000),
[ @BatchSize INT = 0, ]
[ @NotifyAfterRows INT = 0, ]
[ @TimeOut INT = 30, ]
[ @ColumnMappings NVARCHAR(4000) = NULL, ]
[ @BulkCopyOptionsList NVARCHAR(4000) = NULL, ]
[ @SourceCommandTimeout INT = 30, ]
[ @RowsCopied BIGINT = -1 OUTPUT ]
PROC: Uses the .NET SqlBulkCopy class to emulate bcp.exe and the T-SQL BULK INSERT command. It
can connect natively to Microsoft SQL Server and Oracle. It can also be used with Linked Servers to connect
to any DB type that is supported by Linked Servers.
NOTES:
@SourceType:
o Is not case-sensitive
o Can be either MSSQL, Oracle, or NULL
o Defaults to MSSQL if not specified or set to NULL
o Specifying “Oracle” uses native Oracle drivers but initial testing has found that using a
MSSQL SourceType and a Linked Server to Oracle in the SourceQuery was actually faster.
@SourceConnection:
o Connection string to source server
o Defaults to current connection (i.e. “Context Connection”) if not specified or set to NULL
@SourceQuery:
o Query to get the source data
o Can be any query including one that uses a Linked Server
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 108 of 210
@DestinationConnection:
o Connection string to destination server
o If specified must be a Microsoft SQL Server
o Defaults to “Data Source=(local); Integrated Security=true;;” if not specified or set to NULL
@DestinationTableName:
o The name of the Table that the data will import into
@BatchSize:
o Number of Rows per batch
o Setting of 0 will use a single batch
o Default is 0
@NotifyAfterRows:
o The number of rows copied after which a notification is sent showing the user how many rows
total have been copied
o Setting of 0 will not notify
o Default is 0
@TimeOut:
o Number of seconds for the bulk copy operation to complete before it times out
o Setting of 0 will wait indefinitely
o Default is 30
@ColumnMappings:
o Only required if the SourceQuery result rows do not match in number and/or position with the
DestinationTable
o Pipe-delimited list of comma-separated pairs of column mappings
o Each mapping takes the form of: SourceColumn,DestinationColumn
o Columns can be referred to by name or position
o If using column names it IS case-sensitive
o Mappings must be either all names or all positions; you cannot mix specifying names and
positions (even though MSDN says you can)
o Basic example of 3 columns:
IDField,TargetID|NameField,TargetName|Width,ItemWidth
1,2|2,3|3,1
@BulkCopyOptionsList:
o Optional
o Pipe-delimited list of options
o Options are NOT case-sensitive
o Options are:
KeepIdentity = Preserve source identity values. When not specified, identity values
are assigned by the destination.
CheckConstraints = Check constraints while data is being inserted. By default,
constraints are not checked.
TableLock = Obtain a bulk update lock for the duration of the bulk copy operation.
When not specified, row locks are used.
KeepNulls = Preserve null values in the destination table regardless of the settings
for default values. When not specified, null values are replaced by default values
where applicable.
FireTriggers = When specified, cause the server to fire the insert triggers for the
rows being inserted into the database.
UseInternalTransaction = When specified, each batch of the bulk-copy operation
will occur within a transaction.
@SourceCommandTimeOut:
o Number of seconds to wait for the command (i.e. @SourceQuery) to execute
o Setting of 0 will wait indefinitely
o Default is 30
@RowsCopied:
o OUTPUT parameter
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 109 of 210
o Default value: -1
o If set to -1 (the default), it will not track the number of rows copied as it might add drag to the
process. Please keep set to -1 if not using.
PROC: Generates a data-dump much in the same way that BCP, SSIS, and Export Data wizard do. One of
the problems with SSIS is that the Data Flow tasks store the column info (which ones, datatypes, position,
etc.) which makes generating a dynamic result set almost impossible. SSIS also has the problem of not
accepting a variable for the Flat File Destination if you want to dynamically assign the output filename. SSIS
does, however, support text-qualification and column headers: both are important if the file should be easily
readable and importable. BCP on the other hand does support dynamic queries as well column-headers. But
doing text-qualification requires a format-file and doing so when generating a dynamic query is no easy task.
And SQLCMD can do column-headers but not text-qualification. Hence this procedure combines the benefits
of SSIS with the benefits of BCP into a procedure that can do column-headers and text-qualification (like
SSIS) but also supports dynamic queries and output filenames (like BCP). It also supports FirstRow and
LastRow (like BCP).
NOTES:
@Query:
o Can be any query, including an EXEC procedure call
o Value of NULL or empty string simply exits
@TextQualifier:
o Can be any character or set of characters or even an empty string
o Cannot be NULL
o Default value = empty string
@TextQualifyAllColumns:
o If set to True (1) then all fields are enclosed in the @TextQualifer
o If set to False (0) then only the followings fields are enclosed in the @TextQualifier: CHAR,
VARCHAR, TEXT, NCHAR, NVARCHAR, NTEXT, DATETIME, SMALLDATETIME,
UNIQUEIDENTIFIER, SQL_VARIANT, and XML
o Default value = 0 / False
@ColumnHeaderHandling:
o Value is NOT case-sensitive
o Value can be:
Always, NULL, or empty string ‘’: Always display the Column Headers whether there
are results or not
Results: Only display the Column Headers if there is at least one result row
Never: Do not display the Column Headers no matter what
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 110 of 210
o Fields that are to be text-qualified will also have their respective column-header text-qualified
o Default value = Always
@BitHandling:
o How to handle the display of BIT fields
o Value is NOT case-sensitive
o Only three possible values:
Word: Translate as a text-qualified ‘True’ or ‘False’. (This is how SSIS handles
exporting BIT fields)
Letter: Translate as a text-qualified ‘T’ or ‘F’
Number: Translate as a non-text-qualified 1 or 0
o Default value = Word
@FirstRow:
o The first result row to export
o Set to 0 or 1 to ignore (start with first row)
o Default value = 1
@LastRow:
o The last result row to export
o Set to 0 to ignore (no limit)
o Default value = 0
@OutputFilePath:
o The full path to the export file including the filename and extension.
o If set to empty string ‘’ or NULL then the output is sent as a regular query result set
o If set then the file will be created with the exported data
o Behavior if the output file already exists determined by @AppendFile parameter (see below)
o For very large sets of data consider dumping directly to a file and not a result set
o If this field is set you must have EXTERNAL_ACCESS set by doing:
EXEC SQL#.SQLsharp_SetSecurity 2, ‘SQL#.DB’;
o Default value = NULL
@FieldTerminator:
o Only applies if exporting to a file
o Can be any character or set of characters including empty string ‘’
o Value of NULL = tab (\t)
o Default value is a tab (\t)
@RowTerminator:
o Only applies if exporting to a file
o Can be any character or set of characters including empty string ‘’
o Value of NULL = Carriage Return – Line Feed / CRLF (\r\n)
o Default value is a Carriage Return – Line Feed / CRLF (\r\n)
@FileEncoding:
o Only applies if exporting to a file
o Value is NOT case-sensitive
o Value can be:
ASCII
UNICODE [implied Little Endian]
UTF7
UTF8
UnicodeBigEndian
UTF32 [implied Little Endian]
Any other value, including NULL, will select your server’s system default
o Default value = NULL (i.e. your server’s system default)
@AppendFile:
o If file already exists and @AppendFile = 1, exported rows will be appended to the end of it
o If file already exists and @AppendFile = 0, the file will be replaced
o Default value = 0 / False
@RowsExported:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 111 of 210
o OUTPUT variable
o Returns the total number of records / rows exported
o Default value = -1 (so that it is not required to be passed in)
@ConnectionString:
o A full Connection String allowing connection to a remote instance and/or as another Login.
o When using an external connection that is using “Trusted_Connection = true”, impersonation
will automatically be enabled to ensure that a restricted user does not use this proc to come
back in as a more priveldged user (which is essentially what happens when not using
impersonation). Because impersonation is mandatory on external, trusted connections, users
that are not based on a Windows Login cannot use external connections without specifying
the “User ID” and “Password” connection string options.
o If set to NULL or empty string ‘’ it will use the in-process / internal Context Connection
o Default value = ‘Context Connection = true;’
@TextQualifierEscape:
o String that is prefixed to any embedded characters matching the @TextQualifier character in
text-qualified fields, if a @TextQualifier is specified
o Value of NULL will use whatever value @TextQualifier is set to (meaning: duplicate the
embedded text qualifier, just like embedded single-quotes in a T-SQL string)
o Value of empty string ‘’ = no escape character / do not escape embedded text qualifiers
o Default value = NULL
EXAMPLES:
-- export the Employee table from the AdventureWorks DB
-- export as a standard result set (good for testing)
-- do NOT text-qualify all columns, do NOT include column headers
-- include all rows, translate BIT fields to their native 0 or 1
-- use empty text-qualifier to effectively NOT text-qualify any column
EXEC SQL#.DB_BulkExport 'SELECT * FROM AdventureWorks.HumanResources.Employee',
'', 0, 'results', 'number', 0, 0, NULL, NULL, NULL, NULL;
EXEC SQL#.DB_BulkExport
@Query = N'SELECT * FROM dbo.ExportTable;',
@TextQualifier = N'"',
@OutputFilePath = N'C:\temp\ExportTableData.txt',
@ConnectionString = 'server=REMOTE-INST; trusted_connection = true;',
@TextQualifierEscape = N'\';
PROC: Creates tables needed to store the output of DB_GetQueryInfo or alters existing tables to the correct
structure. DDL is either executed immediately, returned as an OUTPUT parameter to run later, or both. Two
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 112 of 210
stored procedures are also created to make interacting with the tables and data easier: DeleteTest and
GetBasicStats.
NOTES:
For use with DB_GetQueryInfo
@TableNamePrefix:
o Set to NULL or empty string to get ‘##QueryInfo’
o The value will be prefixed to the four table names:
o Values can be:
#
#AnyPrefixString
##
##AnyPrefixString
AnyPrefixString
SchemaName.
SchemaName.AnyPrefixString
DatabaseName.SchemaName.
DatabaseName.SchemaName.AnyPrefixString
o If the value starts with a single pound sign “#” (either ‘#’ or ‘#AnyPrefixString’) then the 4
tables must be created ahead of time and the only operation available is to Alter; Create is
not an option as local temporary tables created in a sub-process will not exist once that
process (i.e. the Stored Procedure) ends. In this case, just run the four statements below,
making sure to replace {prefix} with your desired prefix or nothing:
CREATE TABLE #{prefix}ExecutionContext (QueryInfoRemove INT);
CREATE TABLE #{prefix}ExecutionPlans (QueryInfoRemove INT);
CREATE TABLE #{prefix}StatsIO (QueryInfoRemove INT);
CREATE TABLE #{prefix}StatsTime (QueryInfoRemove INT);
o Default value = ‘##QueryInfo’
@TableScript:
o OUTPUT parameter
o Contains the SQL needed to create or alter the tables used by DB_GetQueryInfo
o Set to empty string ‘’ (no need for OUTPUT keyword) to run immediately
o Set to a variable (which needs to be NULL and which it is upon declaration) with the
OUTPUT keyword to save the script to that variable and to als prevent immediate execution.
If creating the tables ahead of time and just needing to Alter, make sure each table has just one
column which is named ‘QueryInfoRemove’ (the datatype is irrelevant).
A stored procedure is auto-generated, using the same @TableNamePrefix value, to make it easy to
remove test runs. Typically it is a good idea to remove the first test run as the additional time it took to
load the CLR objects for this testing stored procedure should not negatively bias the test results. A
good practice is to remove the first test run of any set where the query has changed.
o Name: @TableNamePrefix + ‘DeleteTest’
o Example (assuming default @TableNamePrefix): ##QueryInfoDeleteTest
o Parameters: @FirstQueryInfoID INT [ , @LastQueryInfoID INT = NULL ]
o If @LastQueryInfoID is unspecified or set to NULL, only @FirstQueryInfoID will be deleted.
o If @LastQueryInfoID is set to a positive value, all tests between @FirstQueryInfoID and
@LastQueryInfoID will be deleted.
o If @LastQueryInfoID is set to -1, all tests starting at @FirstQueryInfoID will be deleted.
A stored procedure is auto-generated, using the same @TableNamePrefix value, that provides
aggregated and sorted results for the output captures into the QueryInfo tables. The data is grouped
by the [QueryGroup] field which is populated with the value of the @QueryGroup input parameter.
The results are then ordered by Average Logical Reads.
o Name: @TableNamePrefix + ‘GetBasicStats’
o Example (assuming default @TableNamePrefix): ##QueryInfoGetBasicStats
o Parameters: None
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 113 of 210
EXAMPLES:
-- use default prefix of '##QueryInfo', run immediately
EXEC SQL#.DB_CreateOrAlterQueryInfoTables '', ''
-- use ‘#’ prefix for local temp table, run CREATE TABLE manually, then Alter
CREATE TABLE #ExecutionContext (QueryInfoRemove INT);
CREATE TABLE #ExecutionPlans (QueryInfoRemove INT);
CREATE TABLE #StatsIO (QueryInfoRemove INT);
CREATE TABLE #StatsTime (QueryInfoRemove INT);
RETURNS: NVARCHAR(MAX)
NOTES:
For use with sys.dm_exec_sql_text() Dynamic Management Function (which returns [text] to be
used as SQLText here) and any of the Dynamic Management objects (which return
statement_start_offset and statement_end_offset): sys.dm_exec_query_stats,
sys.dm_exec_requests, sys.dm_exec_cursors, sys.dm_exec_xml_handles,
sys.dm_exec_query_memory_grants, sys.dm_exec_connections
Short-hand for the following T-SQL expression:
SUBSTRING([text], (statement_start_offset / 2) + 1,
(
(CASE statement_end_offset
WHEN -1 THEN DATALENGTH([text])
ELSE statement_end_offset
END - statement_start_offset) / 2
) + 1
)
EXAMPLES:
SELECT SQL#.DB_CurrentSQLStatement(stext.[text], ereq.statement_start_offset,
ereq.statement_end_offset) AS [CurrentStatement],
ereq.*
FROM sys.dm_exec_requests ereq
CROSS APPLY sys.dm_exec_sql_text(ereq.[sql_handle]) stext
PROC: Gets result set meta-data and one-row of returned data for a submitted query.
NOTES:
Similar to sp_describe_first_result_set which first appeared in SQL Server 2012
Unlike sp_describe_first_result_set:
o DB_DescribeResultSets actually runs the submitted query. If the query is not read-only /
SELECT-only and you don’t want the side-effect(s), just wrap the call to
DB_DescribeResultSets in a BEGIN TRAN / ROLLBACK TRAN.
o DB_DescribeResultSets does not have certain limitations such as not working with queries
that use temporary tables
o DB_DescribeResultSets does not guarantee that the described result set will always be
returned by the submitted query; it just describes what was returned for that execution
o DB_DescribeResultSets describes all returned result sets, not just the first one
o DB_DescribeResultSets will include sample data from a single row for each result set
@RowNumberToGetValuesFrom:
o Values < 1 equate to 1
o If value > rows returned for a particular result set, the [Value] field for each column of that
result set will be set to “<no row>”
o Default value = 1
@ResultSetNumberToDescribe:
o Which result set, if there are multiple, to describe
o Set to 0 for ALL
o Default value = 0
@ShowHiddenFields:
o If set to 1 / True, fields that are hidden will be returned with a value of 1 in the [IsHidden] field
o If set to 0 / False, hidden fields will not be returned and all rows will show 0 in [IsHidden]
o Submit the following query to see an example: N'SELECT * FROM sys.objects'
o Default value = 0 / False
@ResultSet:
o OUTPUT parameter
o Contains XML of the same fields and values as the Result Set of this proc if you need to do
further processing on the results (you don’t need to create a table and then INSERT...EXEC)
o If this output is not needed, just pass in empty string ‘’ and without the OUTPUT keyword.
EXAMPLES:
-- Get row 30 from all result sets, showing hidden fields, discard output param
EXEC SQL#.DB_DescribeResultSets N'SELECT * FROM sys.objects', 30, 0, 1, '';
-- Get row 11 from all result sets, no hidden fields, capture output to @Out
DECLARE @Out XML;
EXEC SQL#.DB_DescribeResultSets
@TheQuery = N'SELECT * FROM sys.objects ; SELECT * FROM msdb.dbo.sysjobs',
@RowNumberToGetValuesFrom = 11,
@ResultSetNumberToDescribe = 0,
@ShowHiddenFields = 0,
@ResultSet = @Out OUTPUT;
SELECT @Out;
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 115 of 210
PROC: Transforms one or more serialized result set chunks into one or more result sets.
NOTES:
Multiple result sets of the same structure (column name and datatype per position) can be combined
o Combining requires that result sets of the same structure not be separated by a result set of a
different structure. Meaning, if we have 4 result sets, 2 of structure A and 2 of structure B:
If they are ordered as A, A, B, and B the result will be 2 result sets: A and B
If they are ordered as A, B, A, B the result will be 4 result sets: A, B, A, and B
@SerializedResults VARBINARY(MAX)
o Can accept a single VARBINARY value generated by either DB_SerializeResults or
DB_SerializeResultsInChunks
o Pass in NULL if not using
o Cannot be defaulted
o This field can be used at the same time that @QueryToGetSerializedResults is being used
Same rules apply for combining similar result sets
Result sets from this value are deserialized before any result sets can be deserialized
from the results of the @QueryToGetSerializedResults query
@QueryToGetSerializedResults NVARCHAR(4000)
o Default value (if set to NULL or empty string ‘’ or not specified) ={no query}
o If a query is supplied it needs to return a single VARBINARY field
o Any additional fields will be ignored, but the first field must be VARBINARY
o Any number of rows can be read
o Values returned in the VARBINARY field can be a mix of values generated by
DB_SerializeResults and values generated by DB_SerializeResultsInChunks
o Rows will be processed in order (please see note above about combining result sets)
o This field can be used at the same time that @SerializedResults is being used
Same rules apply for combining similar result sets
Values returned by this query are returned after all result sets have been deserialized
from the @SerializedResults value
@ConnectionString NVARCHAR(500)
o Default value (if set to NULL or empty string ‘’ or not specified) = “Context Connection = true;”
o If using a regular connection with Integrated Security:
Impersonation is automatically applied to prevent a low-priveleged user from using
this as a means to come back in as a privileged user to run restricted commands.
Using impersonation might cause errors if the current security context is already
impersonated or has no association to a Windows SID.
o If set to “Context Connection = true;”
Current security context is used
Standard function restrictions apply except read-only stored procedures can be called
See also: DB_SerializeResults and DB_SerializeResultsInChunks
-- The following global temp table is to be used in all of the following examples
SELECT *
INTO ##Results
FROM SQL#.DB_SerializeResultsInChunks(
N'USE [master]; SELECT TOP 42 DB_NAME() AS [DatabaseName], * FROM sys.objects;
SELECT TOP 437 * FROM sys.columns;
USE [msdb]; SELECT TOP 333 DB_NAME() AS [DatabaseName], * FROM sys.objects;',
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 116 of 210
20, NULL);
-- Get all result sets in the reversed order from how they were originally sent
EXEC SQL#.DB_DeserializeResults
@SerializedResults = NULL,
@QueryToGetSerializedResults = N'SELECT [Results] FROM ##Results ORDER BY
ResultSetNumber DESC, ChunkNumber ASC;';
-- Extract result sets (#1 and #3 of 3); they combine into a single result set
-- due to being the same structure (name and datatype per column)
EXEC SQL#.DB_DeserializeResults
@SerializedResults = NULL,
@QueryToGetSerializedResults = N'SELECT [Results] FROM ##Results WHERE
ResultSetNumber IN (1, 3) ORDER BY ResultSetNumber ASC, ChunkNumber ASC;';
-- Pass in single VARBINARY value containing two results sets (25 rows from [model]
-- and 10 rows from [tempdb]); they combine into a single result set due to being
-- the same structure (name and datatype per column)
DECLARE @ModelObjects VARBINARY(MAX);
SET @ModelObjects = SQL#.DB_SerializeResults(N'USE [model]; SELECT TOP 25 DB_NAME() AS
[DatabaseName], * FROM sys.objects;
USE [tempdb]; SELECT TOP 10 DB_NAME() AS [DatabaseName], * FROM sys.objects;', NULL);
EXEC SQL#.DB_DeserializeResults
@SerializedResults = @ModelObjects
GO
-- Extract result sets (#1 and #3 of 3); AND pass in single VARBINARY value containing
-- two results sets (25 rows from [model] and 10 rows from [tempdb]); they all combine
-- into one result set due to being the same structure (name and datatype per column)
DECLARE @ModelObjects VARBINARY(MAX);
SET @ModelObjects = SQL#.DB_SerializeResults(N'USE [model]; SELECT TOP 25 DB_NAME() AS
[DatabaseName], * FROM sys.objects;
USE [tempdb]; SELECT TOP 10 DB_NAME() AS [DatabaseName], * FROM sys.objects;', NULL);
EXEC SQL#.DB_DeserializeResults
@SerializedResults = @ModelObjects,
@QueryToGetSerializedResults = N'SELECT [Results] FROM ##Results WHERE
ResultSetNumber IN (1, 3) ORDER BY ResultSetNumber ASC, ChunkNumber ASC;';
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 117 of 210
PROC: Generates INSERT statements to recreate data. This procedure can work across all user databases
on a server / instance or a filtered subset, all schemas or a filtered subset, and all tables or a filtered subset.
NOTES:
Only generates INSERT statements to populate data; does NOT create tables or generate any DDL
DB_DumpData works similar to the MySQL utility mysql_dump except that it does not generate any
DDL
Each INSERT ends with a semicolon (;) for compatibility with other RDBMS’s
Columns of datatype TIMESTAMP / ROWVERSION are not included as they cannot be inserted into
directly
@DBPattern:
o A Regular Expression that can be used to filter which Databases are dumped
o If left empty (‘’) then it will match all Databases
o Pattern is NOT case-sensitive
o System databases (master, model, msdb, and tempdb) will never match and cannot be
dumped
@SchemaPattern:
o A Regular Expression that can be used to filter which Schemas are dumped
o If left empty (‘’) then it will match all Schemas
o Pattern is NOT case-sensitive
@TablePattern:
o A Regular Expression that can be used to filter which Tables are dumped
o If left empty (‘’) then it will match all Tables
o Pattern is NOT case-sensitive
@IncludeViews:
o Whether or not to include views as if they were tables
o Only set to 1 if the destination DB has a table that should get this data and not a view of the
same name
o If included, Views are generated after all of the Tables
o If included, Views will be marked with “(VIEW)” after the View name in the comment before
the INSERT statements for the View
@IncludeComputedColumns:
o Whether or not to include column and data for Computed Columns
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 118 of 210
o Only set to 1 if the destination DB has a table with a non-computed column definition for
fields that are computed (i.e. formulas) in the source DB
o If included, any Computed Columns in a table will be noted in the comments before the
INSERT statements for that table
@IdentityHandling:
o How to handle IDENTITY fields
o Valid values are: INSERT, INCLUDE, and EXCLUDE
o Values are NOT case-sensitive
o INSERT:
Include the column and its data
Use SET IDENTITY_INSERT [ON | OFF]
Use when putting data back into a table that has the same IDENTITY field AND you
want to keep the same ID numbers
o INCLUDE
Include the column and its data
Do NOT use SET IDENTITY_INSERT
Use when putting data back into a table that did not specify IDENTITY for this field
o EXCLUDE
Do NOT include the column and its data
Use when putting data back into a table that has the same IDENTITY field but you
want to generate new ID numbers
o If Included or Inserted, the IDENTITY field in a table will be noted in the comments before the
INSERT statements for that table
@DBNameHandling:
o How to format the DB Name in the INSERT statement
o A %s variable will be replaced by the DBName if used
o The %s is not required
o The %s IS case-sensitive
o Leave empty if you do not want any specification of DBName
o If you want to hard-code a DB name then just specify it literally
o If specifying a DBName either via %s or literal, be sure to include the trailing period (.)
o For SQL Server, typical usage = ‘[%s].’
@SchemaNameHandling:
o How to format the Schema Name in the INSERT statement
o A %s variable will be replaced by the Schema Name if used
o The %s is not required
o The %s IS case-sensitive
o Leave empty if you do not want any specification of Schema Name
o If you want to hard-code a Schema name then just specify it literally
o If specifying a Schema Name either via %s or literal, be sure to include the trailing period (.)
o For SQL Server, typical usage = ‘[%s].’
@TableAndColumnNameQualifierLeft:
o What table and column names are prefixed with (e.g. [, “, nothing, etc.)
o For SQL Server use a left square-bracket ([)
@TableAndColumnNameQualifierRight:
o What table and column names are appended with (e.g. ], “, nothing, etc.)
o For SQL Server use a right square-bracket (])
@StringAndDateQualifier:
o What String (CHAR, VARCHAR, VARCHAR(MAX), TEXT, NCHAR, NVARCHAR,
NVARCHAR(MAX), NTEXT, UNIQUEINDETIFIER, XML, and SQL_VARIANT) and Date
(DATETIME and SMALLDATETIME) fields are enclosed in
o For SQL Server use a single-quote (‘) which is represented by specifying two single-quotes
(‘’)
@DateFormat:
o How the date values are converted into text
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 119 of 210
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 120 of 210
@OutputFilePath), it does have the problem of not being able to return more than
8192 or 65535 characters per INSERT statement (which is the total for the full row,
not just the data for each field).
Results to Text | Results to File:
Tools | Options | Query Results | SQL Server | Results to Text | Maximum
number of characters displayed in each column = 8192
Results to File is quick, even if millions of rows of data, but can only show
8192 characters total including the INSERT with Table Name and Column
List. Hence this will not work for tables that have 8000 or more bytes of data.
Results to Grid:
Tools | Options | Query Results | SQL Server | Results to Grid | Maximum
Characters Retrieved / Non-XML Data = 65535
Tools | Options | Query Results | SQL Server | Results to Grid | Include
column headers when copying or saving the results = NOT checked
This method can display more data per row than Results to Text and Results
to File, but might take more memory if several million rows (or more) are
returned
After results are returned, right click inside the results grid and select “Save
Results As...”. After file is saved, change extension from .csv to .sql
EXAMPLES:
/* ALL user DBs, no views, no computed columns, use IDENTITY_INSERT */
EXEC SQL#.DB_DumpData '','','', 0, 0, 'insert', '[%s].', '[%s].', '[', ']',
'''', 121, 'C:\PopulateData.sql'
/* we have a read-only DB that has Sales related data from AdventureWorks for
reporting: DBs starting with "adv", "sales" schema only, include computed
columns, include IDENTITY as regular field since app will not insert here, make
sure insert into AdventureWorksSales DB */
EXEC SQL#.DB_DumpData '^adv','^sales$','', 0, 1, 'include',
'[AdventureWorksSales].', '[%s].', '[', ']', '''', 121, NULL, NULL, NULL, 1, 1
NOTES:
@DBPattern:
o Regular expression for which Databases to include
o Not case-sensitive
o Passing in NULL or empty string ‘’ includes all Databases
o If not specified, defaults to all Databases
@DBExcludePattern:
o Regular expression for which Databases to exclude
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 121 of 210
o Not case-sensitive
o If not specified or passing in NULL, translates to:
^(master|tempdb|model|msdb|resource|distribution|reportserver|
reportservertempdb)$
o Passing in empty string ‘’ does not exclude any Databases
@TablePattern:
o Regular expression for which Tables to include
o Not case-sensitive
o Passing in NULL or empty string ‘’ includes all Tables
o If not specified, defaults to all Tables
@TableExcludePattern:
o Regular expression for which Databases to exclude
o Not case-sensitive
o If not specified or passing in NULL, does not exclude any Tables
o Passing in empty string ‘’ does not exclude any Tables
@PreTableQuery:
o Query to run for each Database that matches @DBPattern and does not match
@DBExcludePattern, before any tables are processed
o Current Database when running DB_ForEach is the same for the session in which
DB_ForEach is called. If the query needs to be run in another Database, @PreTableQuery
could be set to:
'USE [{SQL#DBName}]'
@ForEachTableQuery:
o Query to run for each Table that matches @TablePattern and does not match
@TableExcludePattern
o Current Database is not automatically set to the Database in which the Table is found. If the
query requires that the current Database be the one for the current Table, then be sure to
execute a USE statement in either the @PreTableQuery or the beginning of the
@ForEachTableQuery
@PostTableQuery
o Query to run for each Database that matches @DBPattern and does not match
@DBExcludePattern, after all tables are processed
Database, Schema, and Table name replacement tags are available for use in @PreTableQuery,
@ForEachTableQuery, and @PostTableQuery
Replacement tags are: {SQL#DBName}, {SQL#SchemaName}, {SQL#TableName}, and
{SQL#FullTableName}
Replacement tags ARE case-sensitive
{SQL#SchemaName} and {SQL#TableName} are not contained in [ and ]
{SQL#FullTableName} translates to: [SchemaName].[TableName]
Replacement tag {SQL#DBName} is available in all three TableQuery parameters
Replacement tags {SQL#SchemaName}, {SQL#TableName}, and {SQL#FullTableName} are only
available in @ForEachTableQuery
EXAMPLES:
-- the following works like ForEachDB and separates the commands in case
-- two commands cannot be in the same Query since each Query is a single
-- batch and cannot have GOs
EXEC SQL#.DB_ForEach @PreTableQuery = 'USE {SQL#DBName}',
@PostTableQuery = 'CHECKPOINT'
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 122 of 210
RETURNS: TABLES
(ExecutionPlan XML),
PROC: Gets XML Query Plans and optionally output of STATISTICS IO and STATISTICS TIME.
NOTES:
Results for all three types of information can be saved to tables, including additional info about the
query execution, such as ExecutionTime, Login, Messages, Errors, etc.
Tables to store the output, and stored procedures to help interact with the output, can be created
directly by DB_CreateOrAlterQueryInfoTables or by a script that that Stored Procedure returns.
@ExecutionMode:
o Values:
E / Estimated / NULL
Returns only XML query plans
Results are from SET SHOWPLAN_XML
Empty result sets for IO stats and TIME stats
Default connection string: "context connection=true;"
Connection string can be overridden to use an external connection
A / Actual / empty string ‘’
Returns XML query plans, IO stats, and TIME stats
Results are from:
o STATISTICS XML
o STATISTICS IO
o STATISTICS TIME
Default connection string: "trusted_connection=true;"
Connection string CANNOT use the Context Connection
o Values are NOT case-sensitive
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 123 of 210
EXAMPLES:
-- run query, return stats instead of query results, don't save stats
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'
SELECT *
FROM sys.objects so
INNER JOIN sys.columns sc
ON sc.object_id = so.object_id
ORDER BY so.name, sc.name';
EXEC SQL#.DB_GetQueryInfo @Query = @SQL, @ExecutionMode = N'a'
-- run query, return query results, save stats to global temp tables
EXEC SQL#.DB_CreateOrAlterQueryInfoTables '', '';
DECLARE @SQL NVARCHAR(MAX);
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 124 of 210
EXEC SQL#.DB_GetQueryInfo
@Query = @SQL,
@ExecutionMode = N'a',
@ResultSetContent = N'Query',
@QueryInfoTableNamePrefix = N'##QueryInfo'
RETURNS: NVARCHAR(MAX)
Generates an HTML report from the given Query. The final output is configurable via the “Pre” and “Post”
variables. Since the structure is user-defined, this function can also be used to generate XML.
NOTES:
@Query:
o Can be any query, including an EXEC procedure call
@ColumnHeaderHandling:
o Value is NOT case-sensitive
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 125 of 210
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 126 of 210
@PostTable:
o Any text before the results
o If set to NULL will be: “\t</table>\n”
o String of “{SQL#Query}” will be replaced with the Query
@OutputFilePath:
o The full path to the export file including the filename and extension.
o If this field is empty string ‘’ or NULL then the output is sent as a regular query result set
o If this field is set then the file will be created with the exported data
o If the output file already exists, then the @AppendOutput parameter will control if it will be
over-written or appended to.
o For very large sets of data consider dumping directly to a file and not a result set
o If this field is set you must have EXTERNAL_ACCESS (level 2) set by doing:
EXEC SQL#.SQLsharp_SetSecurity 2, 'SQL#.FileSystem';
o If this field is set then the function’s return value will be empty
@FileEncoding:
o Only applies if exporting to a file
o Value is NOT case-sensitive
o Please see the Note on Encoding Parameters for possible Values.
@EncodeHTML:
o Value cannot be NULL
o Value is NOT case-sensitive
o Value can be:
Empty string ‘’ – does not encode any text into HTML entities
None – encodes HTML entities but no spaces or returns will be translated
Spaces – encodes HTML entities and spaces but not returns
Returns – encodes HTML entities and returns but not spaces
Both – encodes HTML entities including spaces and returns
o See INET_HTMLEncode for examples
@AppendOutput:
o 1 = If file (set by @OutputFilePath) exists, append resulting value to it, else create it.
o 0 = If file (set by @OutputFilePath) exists, overwrite it with the resulting value, else create it.
o Default value is 0 (overwrite).
EXAMPLES:
-- Basic report using default value of including the Column Headers,
-- translate BIT values into words, replace NULL values with "-NULL-",
-- do not limit any rows, and take all default HTML values. Overwrite
-- file if it exists. This can easily be included in an email.
DECLARE @HTMLOutput NVARCHAR(MAX)
SELECT @HTMLOutput =
SQL#.DB_HTMLExport('SELECT TOP 1 * FROM
AdventureWorks.HumanResources.Employee',
'', 'word', '-NULL-', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, '')
PRINT @HTMLOutput
<table border="1">
<tr>
<th>EmployeeID</th>
<th>NationalIDNumber</th>
<th>ContactID</th>
<th>LoginID</th>
<th>ManagerID</th>
<th>Title</th>
<th>BirthDate</th>
<th>MaritalStatus</th>
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 127 of 210
<th>Gender</th>
<th>HireDate</th>
<th>SalariedFlag</th>
<th>VacationHours</th>
<th>SickLeaveHours</th>
<th>CurrentFlag</th>
<th>rowguid</th>
<th>ModifiedDate</th>
</tr>
<tr>
<td>1</td>
<td>14417807</td>
<td>1209</td>
<td>adventure-works\guy1</td>
<td>16</td>
<td>Production Technician - WC60</td>
<td>5/15/1972 12:00:00 AM</td>
<td>M</td>
<td>M</td>
<td>7/31/1996 12:00:00 AM</td>
<td>False</td>
<td>21</td>
<td>30</td>
<td>True</td>
<td>aae1d04a-c237-4974-b4d5-935247737718</td>
<td>7/31/2004 12:00:00 AM</td>
</tr>
</table>
-- EXEC SQL#.SQLSharp_SetSecurity 2
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 128 of 210
@PostTable NVARCHAR(MAX),
@HTMLOutput NVARCHAR(MAX)
SELECT
@PreTable = '<html>
<head>
<title>Report Title</title>
<style>
.SQLTable {border:2px solid black; font-family:verdana;
background:white;}
.SQLHeader {color:white; background:black; text-align:center;}
.SQLRow {background:white;}
TH {padding: 2px;}
TD {border-right:1px dashed black;
border-bottom:1px dashed black;}
TH.Title {color: red; font-weight: bold;}
TD.Title {color: blue; font-weight: bold;}
</style>
</head>
<body bgcolor="#FFFFFF">
</body>
</html>' + @CRLF
-- another example
DECLARE @HTMLOutput NVARCHAR(MAX)
SELECT @HTMLOutput =
SQL#.DB_HTMLExport('SELECT TOP 2 * FROM
AdventureWorks.Production.ProductReview',
'', 'word', '-NULL-', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, 'returns')
PRINT @HTMLOutput
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 129 of 210
RETURNS: UNIQUEIDENTIFIER
Allows for easily generating a GUID value from within a T-SQL function.
NOTES:
SQL Server does not allow for calling NEWID in any T-SQL function: Scalar, Inline TVF, or
Multistatement TVF
The builtin NEWID function can be used in a View, which in turn can be selected from in a T-SQL
function
o The View method is slightly faster, so better for creating many GUIDs in a single SELECT
o The View method might get cached and return the same value more than one (need to find
reference!)
o The DB_NewID function, while slightly slower, will never return the same value
EXAMPLES:
SELECT SQL#.DB_NewID()
-- 0E81C095-9E33-4CEB-BBEB-87B86988DDA5
RETURNS: VARBINARY(MAX)
Transforms one or more result sets from a query into a single binary representation. The binary value can be
stored and/or transported and Deserialized later.
NOTES:
Unlike DB_SerializeResultsInChunks, multiple results are not separated and are all included in the
scalar result (though still separate within that single VARBINARY value).
@Query NVARCHAR(MAX):
o If set to NULL, a NULL will be returned
@ConnectionString NVARCHAR(500)
o Default value (if set to NULL or empty string ‘’) = “Integrated Security=true; Enlist=false;”
o If using a regular connection with Integrated Security:
Impersonation is automatically applied to prevent a low-priveleged user from using
this as a means to come back in as a privileged user to run restricted commands.
Using impersonation might cause errors if the current security context is already
impersonated or has no association to a Windows SID.
o If set to “Context Connection = true;”
Current security context is used
Standard function restrictions apply except read-only stored procedures can be called
See also: DB_DeserializeResults
EXAMPLES:
SELECT SQL#.DB_SerializeResults(N'SELECT * from sys.objects;', NULL);
-- 0x0001000000FFFFFFFF01000000000000000C020000B3696F6E3D332E332E38342E302C2043756C7...
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 130 of 210
Transforms one or more result sets from a query into a binary representation that is spread out among one or
more rows, per result set. The binary value(s) can be stored and/or transported and Deserialized later.
NOTES:
@Query NVARCHAR(MAX):
o If set to NULL, a NULL will be returned
@MaxRowsPerChunk INT
o A chunk is a set of one or more rows.
o One or more chunks make up a result set
o Setting to a value to >= 1
No more than this many rows will be in any chunk
There might be fewer than this many rows if there are not enough rows left
o Setting to a value to < 1 or DEFAULT
Rows are not separated into chunks
One row per result set with all rows for that result set in the VARBINARY value
This setting makes it very easy to pick out one or more result sets from all result sets
@ConnectionString NVARCHAR(500)
o Default value (if set to NULL or empty string ‘’) = “Integrated Security=true; Enlist=false;”
o If using a regular connection with Integrated Security:
Impersonation is automatically applied to prevent a low-priveleged user from using
this as a means to come back in as a privileged user to run restricted commands.
Using impersonation might cause errors if the current security context is already
impersonated or has no association to a Windows SID.
o If set to “Context Connection = true;”
Current security context is used
Standard function restrictions apply except read-only stored procedures can be called
Unlike DB_SerializeResults, multiple results are always separated and cannot be combined.
Separated result sets allow for:
o Picking out one or more specific result sets to keep and discarding the others
o Combining result sets of the same structure (field names and datatypes, per position)
o Both of the above at the same time
See also: DB_DeserializeResults
EXAMPLES:
SELECT * FROM SQL#.DB_SerializeResultsInChunks(N'SELECT * from sys.objects; SELECT *
FROM sys.columns', 0, '');
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 131 of 210
RETURNS: SQL_VARIANT
Allows forcing an error in T-SQL Scalar User-Defined Functions and Multistatement Table-valued Functions.
NOTES:
T-SQL does not allow for using either RAISERROR or THROW, but you can call a function
If any of the three input parameters are set to NULL, a NULL is returned and no error is thrown
Call via SELECT or EXEC (you can’t EXEC a Stored Procedure within a Function, but you can EXEC
a scalar User-Defined Function)
Location:
o Optional parameter
o Additional info to denote in what section of code the error occurred
o When not passing in a value:
If calling via SELECT, pass in the keyword DEFAULT or an empty string ‘’
If calling via EXEC, do not pass in the parameter or pass in an empty string ‘’
LineNumber
o Optional parameter
o Additional info to denote what line the error occurred on
o When not passing in a value:
If calling via SELECT, pass in the keyword DEFAULT or 0
If calling via EXEC, do not pass in the parameter or pass in 0
EXAMPLES:
SELECT SQL#.DB_ThrowException(N'This did not work!', DEFAULT, DEFAULT)
Allows catching errors in T-SQL Scalar User-Defined Functions and Multistatement Table-valued Functions.
NOTES:
T-SQL does not allow for using TRY...CATCH, but you can call a function
Passing in NULL returns an empty result set
“Context Connection” (the internal / in-process connection) is used, meaning:
o Even though random SQL can be executed, there are no security concerns as the security
context is that of whoever is selecting from this function
o No DML or DDL is allowed, or anything that can change state (i.e. side-effecting)
Unlike with T-SQL functions:
o you can execute stored procedures, but all of the other restrictions still apply (such as no SET
commands, no DDL or DML, etc)
o you can do Dynamic sql (whatever is passed into the @SQL parameter is by definition
Dynamic SQL)
The [ErrorHasOccurred] field is a direct indication of an error happening so that whether or not the
operation failed does not need to be indirectly determined by checking any of the error detail fields.
If no error occurs:
o [ErrorHasOccurred] field will be set to 0.
o [ErrorMessage] will be NULL
o [ErrorNumber], [ErrorSeverity], and [ErrorState] will be 0
o [ReturnValue] can be populated by setting the local variable @SQL#Output:
There is no need to declare this variable as it already exists
The variable is NVARCHAR(MAX)
Anything can be passed back.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 133 of 210
Multiple values, tables, multiple tables, etc can be passed back as XML. Just
SELECT the variable(s) and/or table(s) using FOR XML. By default the FOR XML clause
outputs an NVARCHAR(MAX) containing XML and is not an XML datatype unless
the “, TYPE” option is added (but don’t as that will cause an error).
If an error does occur:
o [ErrorHasOccurred] field will be set to 1.
o [ErrorMessage], [ErrorNumber], [ErrorSeverity], and [ErrorState] will be set appropriately.
o [ReturnValue] field will be NULL
Pass values in by concatenating them directly into the SQL that is being passed in to execute.
o Just like with the ReturnValue output, passing in multiple items (including one or more tables)
can be done by packaging everything in XML.
EXAMPLES:
-- simple query / no error / no return
SELECT * FROM SQL#.DB_TryCatch(N'DECLARE @T INT; SET @T = 5; SELECT @T / 2.0;');
-- simple query / no error / return val as XML (to pass back a table)
SELECT *, DATALENGTH(ReturnValue) AS [OutputBytes], CONVERT(XML, ReturnValue) AS [InXML]
FROM SQL#.DB_TryCatch(N'SET @SQL#Output = (SELECT TOP 19 * FROM sys.objects FOR XML RAW);');
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 134 of 210
IF (@ErrorHasOccured = 0)
BEGIN
SET @NumObjects = CONVERT(INT, @ReturnValue);
END;
ELSE
BEGIN
IF (@ErrorNumber = 208)
BEGIN
SET @NumObjects = -1;
END;
ELSE
BEGIN
DECLARE @ProcCall NVARCHAR(500);
SET @ProcCall = N'dbo.TestFunc(N''' + @DatabaseName + N''')';
SET @ErrorMessage = @ErrorMessage + NCHAR(10) + NCHAR(10) + NCHAR(9) + @SQL;
EXEC SQL#.DB_ThrowException @ErrorMessage, @ProcCall, 18;
END;
END;
RETURN @NumObjects;
END;
GO
-- no error
SELECT dbo.TestFunc(N'master') AS [NumObjects];
-- 91
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 135 of 210
-- Using the [TestFunc] function just created, cause an error and catch it
CREATE PROCEDURE #Temp2 AS
BEGIN TRY
SELECT dbo.TestFunc(N'bad]name') AS [NumObjects], 1 AS [y];
END TRY
BEGIN CATCH
SELECT 1 AS [Error];
PRINT '---------------------';
PRINT ERROR_MESSAGE();
PRINT '---------------------';
PRINT ERROR_PROCEDURE();
PRINT '---------------------';
END CATCH;
GO
EXEC #Temp2;
NumObjects y
Error
1
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 136 of 210
DatabaseName TableName
CaseSensitiveCollation test1
CaseSensitiveCollation test2
Database2 Table1
Database2 Table2
ReportServer Keys
ReportServer History
ReportServer DBUpgradeHistory
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 137 of 210
Convert
Convert functions allow for transforming data into a different representative that can be converted back (unlike
Hash functions).
Convert_BinaryToHexString
Convert_BinaryToHexString(BinaryValue VARBINARY(MAX))
RETURNS: NVARCHAR(MAX)
NOTES:
Starting in SQL Server 2008, the CONVERT function can accomplish this same functionality. Use a
“style” setting of 1 to include the “0x” on the left or a setting of 2 to not include the “0x”, just as this
SQL# function does:
SELECT CONVERT(VARCHAR, 0x12A5, 2)
EXAMPLES:
SELECT SQL#.Convert_BinaryToHexString(0x48656c6c6f20576f726c6421)
-- 48656C6C6F20576F726C6421
Convert_DateTimeToMSIntDate
Convert_DateTimeToMSIntDate(RealDate DATETIME)
RETURNS: INT
NOTES:
Same as: CONVERT(INT, DATEADD(HOUR, -12, @RealDate))
Microsoft Int Date Epoch (Day 0) = 1900-01-01
See also: Convert_MSIntDateToDateTime
EXAMPLES:
SELECT SQL#.Convert_DateTimeToMSIntDate('03/15/2010')
-- 40250
Convert_FromBase64
Convert_FromBase64(EncodedValue NVARCHAR(MAX))
RETURNS: VARBINARY(MAX)
EXAMPLES:
SELECT SQL#.Convert_FromBase64('SGVsbG8gV29ybGQh')
-- 0x48656C6C6F20576F726C6421
Convert_HexStringToBinary
Convert_HexStringToBinary(HexStringValue NVARCHAR(MAX))
RETURNS: VARBINARY(MAX)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 138 of 210
NOTES:
Starting in SQL Server 2008, the CONVERT function can accomplish this same functionality. Use a
“style” setting of 1 if the string has the “0x” on the left (the “0x” is required if using a “style” of 1) or a
setting of 2 if it does not include the “0x”, just as this SQL# function does:
SELECT CONVERT(VARBINARY, 12A5, 2)
EXAMPLES:
SELECT SQL#.Convert_HexStringToBinary('48656C6C6F20576F726C6421')
-- 0x48656C6C6F20576F726C6421
Convert_HtmlToXml
Convert_HtmlToXml(Document NVARCHAR(MAX), DocumentUri NVARCHAR(MAX), CaseFolding
NVARCHAR(50))
RETURNS: NVARCHAR(MAX)
Converts HTML to well formed XML by adding missing quotes, empty attribute values, ignoring duplicate
attributes, case folding on tag names, adding missing closing tags based on SGML DTD information, and so
on.
NOTES:
Document is any HTML text
DocumentUri is the location of any HTML page
CaseFolding:
o Values are NOT case-sensitive
o Values:
ToUpper – upper-cases all tags
ToLower – lower-cases all tags
{anything else} – doesn’t change tag casing
Sometimes requires having External Access permissions set on the SQL#.SgmlReader Assembly,
especially if using DocumentUri:
EXEC SQL#.SQLsharp_SetSecurity 2, 'SQL#.SgmlReader'
Either Document or DocumentUri needs to have a value.
If both Document and DocumentUri have a value, DocumentUri will be used
This is not a replacement for INET_GetWebPages as this function modifies the document being
retrieved
EXAMPLES:
PRINT SQL#.Convert_HtmlToXml('
<Html>
<body>
<P class=MsoNormal dir=ltr
style="MARGIN: 0pt;" align=left><?xml:namespace
prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags"
/><ST1:PERSONNAME></ST1:PERSONNAME></P>
</body>
</html>
', NULL, 'ToLower')
/*
<html>
<body>
<p class="MsoNormal" dir="ltr" style="MARGIN: 0pt;" align="left"><?namespace
prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags"
?><st1:personname xmlns:st1="#unknown"></st1:personname></p>
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 139 of 210
</body>
</html>
*/
Convert_MSIntDateToDateTime
Convert_MSIntDateToDateTime (MSIntDate INT)
RETURNS: DATETIME
NOTES:
Same as: CONVERT(DATETIME, @MSIntDate)
Microsoft Int Date Epoch (Day 0) = 1900-01-01
See also: Convert_DateTimeToMSIntDate
EXAMPLES:
SELECT SQL#.Convert_MSIntDateToDateTime(40250)
-- 2010-03-15 00:00:00.000
Convert_ROT13
Convert_ROT13(TextValue NVARCHAR(MAX))
RETURNS: NVARCHAR(MAX)
NOTES:
ROT13 simply shifts the English alphabet characters 13 places and since there are 26 letters,
applying it twice to the same string will bring everything back to where it started. Hence, the ROT13
algorithm decodes what it has already encoded.
EXAMPLES:
SELECT SQL#.Convert_ROT13('25) This is a test.')
-- 25) Guvf vf n grfg.
SELECT SQL#.Convert_ROT13('25) Guvf vf n grfg.')
-- 25) This is a test.
Convert_ToBase64
Convert_ToBase64(UnencodedValue VARBINARY(MAX), Base64FormattingOption NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
NOTES:
Base64FormattingOption = InsertLineBreaks or None
Base64FormattingOption is NOT case-sensitive
EXAMPLES:
SELECT SQL#.Convert_ToBase64(0x48656c6c6f20576f726c6421,
'InsertLineBreaks')
-- SGVsbG8gV29ybGQh
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 140 of 210
Convert_UUDecode
Convert_UUDecode(EncodedValue NVARCHAR(MAX))
RETURNS: VARBINARY(MAX)
NOTES:
Do not include the “begin” and “end” lines, just the actual encoded lines
EXAMPLES:
DECLARE @UUSource VARBINARY(MAX),
@UUEncoded NVARCHAR(MAX)
SET @UUSource = 0x325B2F99D4F578BD4207A84CE31200D3FF73
SET @UUEncoded = SQL#.Convert_UUEncode(@UUSource)
SELECT @UUEncoded, SQL#.Convert_UUDecode(@UUEncoded)
-- 2,ELOF=3U>+U"!ZA,XQ(`T_]S 0x325B2F99D4F578BD4207A84CE31200D3FF73
Convert_UUEncode
Convert_UUEncode(EncodedValue VARBINARY(MAX))
RETURNS: NVARCHAR(MAX)
NOTES:
Does not include the “begin ### -” and “end” lines
EXAMPLES:
DECLARE @UUSource VARBINARY(MAX),
@UUEncoded NVARCHAR(MAX)
SET @UUSource = 0x325B2F99D4F578BD4207A84CE31200D3FF73
SET @UUEncoded = SQL#.Convert_UUEncode(@UUSource)
SELECT @UUEncoded, SQL#.Convert_UUDecode(@UUEncoded)
-- 2,ELOF=3U>+U"!ZA,XQ(`T_]S 0x325B2F99D4F578BD4207A84CE31200D3FF73
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 141 of 210
Sys_IndexName
Sys_IndexName(DatabaseID INT, ObjectID INT, IndexID INT)
RETURNS: SYSNAME
Returns the name of the specified Index on the specified Object within the specified Database.
NOTES:
Works similarly to OBJECT_NAME() in that you do not need to be in the database where the object
exists in order to get the correct result
For use with Dynamic Management objects that return all three input values, such as
sys.dm_db_index_usage_stats
EXAMPLES:
SELECT DB_NAME(stat.database_id) AS [DatabaseName],
OBJECT_NAME(stat.[object_id], stat.database_id) AS [TableName],
SQL#.Sys_IndexName(stat.database_id, stat.[object_id], stat.index_id) AS [IndexName],
*
FROM sys.dm_db_index_usage_stats stat
Sys_Objects
Sys_Objects(DBNamePattern NVARCHAR(MAX), IncludeSystemDatabases BIT)
RETURNS: TABLE (database_name SYSNAME, database_id INT, name SYSNAME, object_id INT,
principal_id INT, schema_id INT, parent_object_id INT, type NCHAR(2), type_desc NVARCHAR(60),
create_date DATETIME, modify_date DATETIME, is_ms_shipped BIT, is_published BIT,
is_schema_published BIT, schema_name SYSNAME, parent_name SYSNAME, parent_schema_id INT,
parent_type NCHAR(2), parent_type_desc NVARCHAR(60), parent_schema_name SYSNAME)
Returns information from sys.objects from all databases matching the DBNamePattern with additional
schema and parent_object information.
NOTES:
DBNamePattern
o is a full regular expression. If you want to match all databases, pass in empty string ‘’
o is NOT case-sensitive
IncludeSystemDatabases when set to 0 will exclude: master, model, msdb, tempdb, and any
database that is a distributor (only on replication distributor nodes)
EXAMPLES:
SELECT * FROM SQL#.Sys_Objects('', 1) WHERE [type] IN ('p', 'pc')
-- return all procs (SQL and CLR) from ALL DBs, even system DBs
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 142 of 210
XML_EscapeContent
XML_EscapeContent(StringValue NVARCHAR(MAX))
RETURNS: XML
NOTES:
NULL input returns NULL
EXAMPLES:
SELECT SQL#.XML_EscapeContent(N'<a>Hello&"Goodbye"?</a>')
-- <a>Hello&amp;"Goodbye"?</a>
XML_Transform
XML_Transform(SourceXML XML, SourceXMLPath NVARCHAR(4000), SourceXSL XML, SourceXSLPath
NVARCHAR(4000), XSLTParameters SQL#.Type_HashTable, OutputFilePath NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
Returns the XML, supplied directly or from a file, transformed according to the XSL, supplied directly or from a
file. It can be returned either directly or to a file. Optionally XSLT parameters can be supplied.
NOTES:
XML must be supplied either directly via SourceXML or from a file via SourceXMLPath.
If both SourceXML and SourceXMLPath are supplied, SourceXMLPath will be used.
XSL must be supplied either directly via SourceXSL or from a file via SourceXSLPath.
If both SourceXSL and SourceXSLPath are supplied, SourceXSLPath will be used.
When not supplying XSLT Parameters, pass in NULL
XSLT Parameters are useful for run-time substitutions, especially when getting XML and XSL from
tables and/or files.
If OutputFilePath is specified it will be used and NULL will be returned from the function
If OutputFilePath is empty string or NULL, the transformed XML will be returned from the function
See the following for some output options: http://www.w3schools.com/xsl/el_output.asp
EXAMPLES:
-- Run all of the following together, including the two SELECTs to see the difference
DECLARE @SourceXML XML, @SourceXSL XML
DECLARE @Params SQL#.Type_HashTable
SET @Params = @Params.AddItem('reportedby', 'Solomon')
SET @Params = @Params.AddItem('hourlyrate', '100')
SELECT @Params.Count;
</project>
<project ID="456">
<title>Marketing Brochure</title>
<hours>11.75</hours>
</project>
</projects>
'
--------------
Reported by: <xsl:value-of select="$reportedby"/>
</invoice>
</xsl:template>
</xsl:stylesheet>
'
SELECT SQL#.XML_Transform(@SourceXML, '', @SourceXSL, '', @Params, '')
SELECT SQL#.XML_Transform(@SourceXML, '', @SourceXSL, '', NULL, '')
MyCompany, Inc.
--------------
Reported by: Solomon
XML_UnescapeContent
XML_UnescapeContent(XMLValue XML)
RETURNS: NVARCHAR(MAX)
Returns the XML, as NVARCHAR, with any XML-specific characters properly unescaped.
NOTES:
NULL input returns NULL
EXAMPLES:
SELECT SQL#.XML_UnescapeContent(N'<a>Hello&amp;"Goodbye"?</a>')
-- <a>Hello&"Goodbye"?</a>
SELECT SQL#.XML_UnescapeContent(N'"Who Knew?"')
-- "Who Knew?"
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 144 of 210
LookUp
LookUp functions provide commonly used static data that far too many applications duplicate in tables.
LookUp_GetCountryInfo
LookUp_GetCountryInfo(SearchCode NVARCHAR(4000))
Provides ISO-based information on countries. All countries can be returned at once (to create a drop-down
list perhaps) or a single country’s information can be returned based on the SearchCode passed in. There
are 244 countries listed.
NOTES:
SearchCode can be either the Numeric, TwoLetterCode, or ThreeLetterCode; if either Two or Three
LetterCode, then it is NOT case-sensitive
If SearchCode is empty '' or NULL then all Countries are returned
By default data is sorted by Name field
FlagImage column of result set is a PNG picture file of the flag for that country. This can be used on
websites rather easily by streaming the binary data to a webpage that is used as the SRC of an IMG
tag while changing the mime-type HTTP header to “image/png”. If you would rather store the images
on disk in actual png files, then you can export all of the flag images into separate files using the
following SQL:
EXEC SQL#.SQLSharp_SetSecurity 2
SELECT SQL#.File_CreateDirectory('C:\SQL#CountryFlags')
SELECT *, SQL#.File_WriteFileBinary('C:\SQL#CountryFlags\' +
cinfo.TwoLetterCode + '.png', cinfo.FlagImage,
'Create', '')
FROM SQL#.LookUp_GetCountryInfo('') cinfo
WHERE cinfo.FlagImage IS NOT NULL
The information is maintained by the ISO (International Standards Organization) and is subject to
change, although not frequently. SQL# will be updated if / when it does change.
EXAMPLES:
SELECT * FROM SQL#.LookUp_GetCountryInfo('') -- get all Country Info
SELECT * FROM SQL#.LookUp_GetCountryInfo('008') -- get Info for Albania
SELECT * FROM SQL#.LookUp_GetCountryInfo('FI') -- get Info for Finland
SELECT * FROM SQL#.LookUp_GetCountryInfo('usa') -- get Info for US
SELECT * FROM SQL#.LookUp_GetCountryInfo('') ORDER BY TwoLetterCode
-- get all Country Info sorted by the TwoLetterCode
LookUp_GetStateInfo
LookUp_GetStateInfo(SearchCode NVARCHAR(4000), USStatesOnly BIT)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 145 of 210
Provides US Postal Service-based information on states and territories. All states can be returned at once (to
create a drop-down list perhaps) or a single state’s information can be returned based on the SearchCode
passed in. The list can also be filtered to show only actual US states. There are 82 states and territories
listed.
NOTES:
SearchCode can be either the Numeric or TwoLetterCode; if TwoLetterCode, then is NOT case-
sensitive
If SearchCode is empty '' or NULL then all States are returned, unless USStatesOnly is True / 1 then
all US States are returned
The numeric code is the FIPS (Federal Information Processing Standard) code, used by various US
Govnerment departments
If USStatesOnly is set to True / 1 then Washington, D.C. is also returned
By default data is sorted by Name field
FlagImage column of result set is reserved for future use
The information is maintained by the United States Postal Service and is subject to change, although
not frequently. SQL# will be updated if / when it does change.
EXAMPLES:
SELECT * FROM SQL#.LookUp_GetStateInfo('', '') -- get all State Info
SELECT * FROM SQL#.LookUp_GetStateInfo('', 'US') -- get all US States
SELECT * FROM SQL#.LookUp_GetStateInfo('AS', '') -- get only 1 state
SELECT * FROM SQL#.LookUp_GetStateInfo('AS', 'US')
-- returns nothing since 'AS' is not a US state
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 146 of 210
Operating System
The OS functions reside in the SQL#.OS assembly.
If you use any of the functions that access the Operating System, then this assembly will need a security
setting of EXTERNAL_ACCESS (2). You can set this by executing the following query:
If you do not want to have this assembly in your system at all, you can do either of the following:
1) Do not install the SQL#.OS assembly by setting the @InstallSQL#OS variable (towards the top of
the script) to 0 before installing
2) Uninstall the assembly by running:
EXEC [SQL#].[SQLsharp_Uninstall] N'SQL#.OS'
OS_EventLogRead
OS_EventLogRead(LogName NVARCHAR(4000), MachineName NVARCHAR(4000), Source
NVARCHAR(4000), EntryType NVARCHAR(4000), InstanceID NVARCHAR(4000), Category
NVARCHAR(4000), UserName NVARCHAR(4000), Message NVARCHAR(4000), TimeGeneratedBegin
DATETIME, TimeGeneratedEnd DATETIME, IndexBegin INT, IndexEnd INT, RegExOptionsList
NVARCHAR(4000))
RETURNS: TABLE (Index INT, Category NVARCHAR(500), EntryType NVARCHAR(50), InstanceId BIGINT,
Source NVARCHAR(500), TimeGenerated DATETIME, TimeWritten DATETIME, UserName
NVARCHAR(100), Message NVARCHAR(4000), Data VARBINARY(MAX))
NOTES:
LogName:
o Needs to be a valid Event Log name such as: System, Application, or Security.
o Is not case-sensitive.
o Can also be the Event Log filename, such as: OSession for “Microsoft Office Sessions”
MachineName:
o can be set to NULL or empty string ‘’ to mean the local machine
Source:
o Is a Regular Expression controlled by RegExOptionsList
EntryType:
o Is a Regular Expression controlled by RegExOptionsList
o Valid Entry Type are: Error, Information, Warning, Failure Audit, and Success Audit
InstanceID:
o Underlying value is an INT
o Parameter is a Regular Expression controlled by RegExOptionsList so that you have more
control over what number(s) to filter on.
Category:
o Is a Regular Expression controlled by RegExOptionsList
UserName:
o Is a Regular Expression controlled by RegExOptionsList
Message:
o Is a Regular Expression controlled by RegExOptionsList
TimeGeneratedBegin:
o The minimum time in the result set or starting time
o Set to NULL to mean “no minimum” and to pull from the beginning
TimeGeneratedEnd:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 147 of 210
EXAMPLES:
-- read all Events from the System log
SELECT * FROM SQL#.OS_EventLogRead('System', '', '', '', '', '', '', '', NULL,
NULL, 0, 0, '')
-- read only Error and Warning Events from the Application log,
-- ignoring the case of the EventTypes
SELECT * FROM SQL#.OS_EventLogRead('Application', '', '', '(error|warning)', '',
'', '', '', NULL, NULL, 0, 0, 'ignorecase')
-- read all Events from the Application log that came from SQL Server,
-- starting on May 1st, 2009 at 15:30 (or 3:30 PM)
SELECT * FROM SQL#.OS_EventLogRead('Application', '', 'MSSQLSERVER', '', '', '',
'', '', '05/01/2009 15:30', NULL, 0, 0, '')
OS_EventLogWrite
OS_EventLogWrite(LogName NVARCHAR(4000), MachineName NVARCHAR(4000), Source
NVARCHAR(4000), EntryType NVARCHAR(4000), InstanceID INT, Category SMALLINT, Message
NVARCHAR(4000), BinaryData VARBINARY(8000))
RETURNS: NVARCHAR(4000)
NOTES:
LogName must be a valid Event Log on the system, either Event Log name (e.g. System or
Application) or Event Log Filename (e.g. OSession for OSession.evt)
MachineName can be set to NULL or empty string ‘’ to mean local machine
Source can be an existing Source for the Event Log or a new one that will be created the first time it
is used in the Event Log. Please keep in mind that a Source can only exist in one Event Log so if you
create “MyApp” in “Application” then you cannot use “MyApp” as a Source in “System” or any other
Even Log. If you try to use a Source that has already been created in another Event Log you will get
an error.
Entry Type can be: Error, Information, Warning, Audit Failure, or Audit Success
Entry Type is not case-sensitive
Category is any value you choose
Message cannot be NULL
BinaryData can be set to NULL
Always returns empty string ‘’
Designed as a Function instead of a Procedure so that it can be used in set-based operations
EXAMPLES:
-- write an Informational message to the Application Log with
-- a Source of SQL# and no BinaryData
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 148 of 210
OS_GenerateTone
OS_GenerateTone(Frequency INT, Duration INT)
RETURNS: NVARCHAR(4000)
NOTES:
Frequency is between 37 and 32767 hertz
Duration is in milliseconds
Always returns empty string ‘’
Designed as a Function instead of a Procedure so that it can be used in set-based operations
Volume is controlled only through the “PC Speaker” volume control and is not affected by the master
volume outside of the “mute” function.
EXAMPLES:
SELECT SQL#.OS_GenerateTone(90, 1000)
OS_MachineName
OS_MachineName()
RETURNS: NVARCHAR(4000)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 149 of 210
Returns the Computer name of the machine that SQL Server is running on.
NOTES:
This Function only requires EXTERNAL_ACCESS (2) permissions
This should be equivalent to the T-SQL function:
SERVERPROPERTY('MachineName')
NOTES:
ProcessIDs is a comma-separated list of Process IDs
You can find general ProcessIDs by going to Task Manager, selecting the View menu, selecting the
“Select Columns...” sub-menu, and checking the box for “PID (Process Identifier)”.
You cannot see information on Processes owned by “SYSTEM” but you should be able to see info for
“LOCAL SERVICE” and “NETWORK SERVICE” Processes as well as any Process started by the
account running the “SQL Server” Process.
If you are not allowed to see the Process information the “MainModule” field will display: Access is
denied.
If a Process is taking too long and you notice that the “Responding” field is set to 0, consider using
OS_ProcessKill
EXAMPLES:
SELECT * FROM SQL#.OS_ProcessGetInfo('2232,2724,0,1632,3648,1356')
RETURNS: NVARCHAR(4000)
NOTES:
ProcessID is the ID of the Process as returned by OS_ProcessStart
ProcessName is the name of the program running under the ProcessID and is a safe-guard to make
sure you do not kill another Process with the same ID. This is just in case the Process you wanted to
kill ended and another one started with the same ProcessID (even if that is unlikely to happen).
If the program started by ProcessStart is a .BAT or .CMD script, then use “CMD” as ProcessName
ProcessName is NOT case-sensitive
Return string is a success or error message
Designed as a Function instead of a Procedure so that it can be used in set-based operations
ProcessID must be owned / started by the account that runs the SQL Server process; you are not
able to kill Processes started by other users or even the main “SQL Server” Process
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 150 of 210
ProcessID must be a processes started by the OS_ProcessStart function; you cannot kill the main
SQL Server process even though the same user account started that process
EXAMPLES:
SELECT SQL#.OS_ProcessKill(1234, 'NotePad')
RETURNS: INT
Runs the command specified by FilePath like xp_cmdshell but does so asynchronously so that control returns
immediately and proceeds to the next T-SQL command rather than waiting for the Process to complete.
Because the process is running separately from the SQL Session, no output from the command is returned
unlike with xp_cmdshell.
Notes:
FilePath can be a full path to a command or a relative path or just a command / program name if it
can be found in the PATH environment variable
Arguments can be NULL, empty string ‘’, or any set of command-line parameters
If WorkingDirectory is set to NULL or empty string ‘’ it might default to C:\Windows\System32 so it is
best to set this value
ProcessID return value can be used with both OS_ProcessGetInfo and OS_ProcessKill
Permissions for the Process / Command should be same as Login running the “SQL Server” Process
Can be used to call DTExec, OSQL, SQLCMD, etc.
EXAMPLES:
-- NotePad will not be visible so should not be used normally
-- but works as an example
DECLARE @ProcessID INT
SELECT @ProcessID = SQL#.OS_ProcessStart('NotePad', NULL, 'C:\')
SELECT * FROM SQL#.OS_ProcessGetInfo(CONVERT(NVARCHAR(20), @ProcessID))
SELECT SQL#.OS_ProcessKill(@ProcessID, 'NotePad')
OS_StartTime
OS_StartTime()
RETURNS: DATETIME
Returns the Date and Time of when the machine was started. This is more consistent than inferring from:
DATEADD(MILLISECOND, (SQL#.OS_Uptime() * -1), GETDATE())
OS_Uptime
OS_Uptime()
RETURNS: INT
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 151 of 210
Twitter
Twitter functions allow you to get and send message on Twitter.com via simple T-SQL commands. The
following assemblies need to be installed in order to use the Twitter functions: SQL#, SQL#.JsonFx,
SQL#.Twitterizer, and SQL#.TypesAndAggregates.
All Twitter Functions, because they use the Internet, require a security setting of EXTERNAL_ACCESS (2).
You can set this by executing the following query:
Be sure to note that Twitter.com does enforce “rate limits” and will not allow over a certain amount of calls per
hour. Please see http://apiwiki.twitter.com/FAQ for more information regarding “rate limits”, as well as the
Twitter Rate Limit Chart.
IMPORTANT: Please see the SQL# Twitter setup guide for details on how to set up your Twitter
Application:
http://www.SQLsharp.com/download/SQLsharp_TwitterSetup.pdf
If you do not want to have this Assembly in your system at all, you can do either of the following:
3) Do not install the SQL#.Twitterizer assembly by setting the @InstallSQL#Twitterizer variable
(towards the top of the script) to 0 before installing
4) Uninstall the assembly by running:
EXEC [SQL#].[SQLsharp_Uninstall] N'SQL#.Twitterizer'
If you want to use any of the Optional Twitter Parameters, do the following to set the value of the
@OptionalParameters input parameter:
Please note, invalid Unicode escape sequences, such as \ud8c3, will display as a question mark (?) since
there is no way to translate them.
Twitter_BlockUser
Twitter_BlockUser(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), ScreenName NVARCHAR(20))
NOTES:
ScreenName is the user to block
Returns the blocked user’s info
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 152 of 210
If you try to Block a user that is already in the authenticating user’s “Blocks” list, you will NOT get an
error
Twitter_CreateFavorite
Twitter_CreateFavorite(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), StatusID BIGINT)
Twitter_DestroyDirectMessage
Twitter_DestroyDirectMessage(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100),
AccessToken NVARCHAR(100), AccessTokenSecret NVARCHAR(100), MessageID BIGINT)
RETURNS: NVARCHAR(4000)
NOTES:
Always returns empty string ‘’
Designed as a Function instead of a Procedure so that it can be used in set-based operations
Twitter_DestroyFavorite
Twitter_DestroyFavorite(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), StatusID BIGINT)
Twitter_DestroyStatus
Twitter_DestroyStatus(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), StatusID BIGINT)
RETURNS: NVARCHAR(4000)
NOTES:
Always returns empty string ‘’
Designed as a Function instead of a Procedure so that it can be used in set-based operations
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 153 of 210
Twitter_FollowUser
Twitter_FollowUser(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), ScreenName NVARCHAR(20))
NOTES:
ScreenName is the user to follow
Returns the followed user’s info
If you try to Follow a user that is already in the authenticating user’s “Friends” list, you will get the
following error:
“<error>Could not follow user: XXXXXXX is already on your list.</error> --->
System.Net.WebException: The remote server returned an error: (403) Forbidden.”
Twitter_GetBlocks
Twitter_GetBlocks(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100))
Twitter_GetFavorites
Twitter_GetFavorites(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), OptionalParameters Type_HashTable)
Returns the top 20 statuses marked as “favorite” by the authenticating user or the User specified in the
OptionalParameters.
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o user_id = The ID of the user for whom to request a list of favorite statuses
o screen_name = The screen name of the user for whom to request a list of favorite statuses
o count = The number of results to retrieve. Default = 20 and cannot be over 200.
o since_id = Returns results with an ID greater than (that is, more recent than) the specified ID
o max_id = Returns results with an ID less than (that is, older than) or equal to the specified ID.
Twitter_GetFollowers
Twitter_GetFollowers(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100))
Twitter_GetFriends
Twitter_GetFriends(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100))
Twitter_GetHomeTimeline
Twitter_GetHomeTimeline(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100),
AccessToken NVARCHAR(100), AccessTokenSecret NVARCHAR(100), OptionalParameters
Type_HashTable)
Returns the 20 most recent statuses, including retweets if they exist, posted by the authenticating user and
the user's they follow. This is the same timeline seen by a user when they login to twitter.com. This method is
identical to statuses/friends_timeline, except that this method always includes retweets. This method is can
only return up to 800 statuses, including retweets.
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o since_id = Returns results with an ID greater than (that is, more recent than) the specified
ID. There are limits to the number of Tweets which can be accessed through the API. If the
limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID
available.
o max_id = Returns results with an ID less than (that is, older than) or equal to the specified ID.
o count = The number of records to retrieve. Must be <= 200. Default = 20.
o exclude_replies = This parameter will prevent replies from appearing in the returned
timeline. Using exclude_replies with the count parameter will mean you will receive up-to
count tweets — this is because the count parameter retrieves that many tweets before
filtering out retweets and replies..
Twitter_GetMentions
Twitter_GetMentions(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), OptionalParameters Type_HashTable)
Returns the 20 most recent mentions (status containing @username) for the authenticating user.
The timeline returned is the equivalent of the one seen when you view your mentions on twitter.com.
This method can only return up to 800 statuses.
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o since_id = Returns results with an ID greater than (that is, more recent than) the specified
ID. There are limits to the number of Tweets which can be accessed through the API. If the
limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID
available.
o max_id = Returns results with an ID less than (that is, older than) or equal to the specified ID.
o count = Specifies the number of tweets to try and retrieve, up to a maximum of 200. The
value of count is best thought of as a limit to the number of tweets to return because
suspended or deleted content is removed after the count has been applied.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 156 of 210
Twitter_GetMessages
Twitter_GetMessages(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), OptionalParameters Type_HashTable)
Returns the 20 most recent Direct Messages sent to the authenticating user.
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o since_id = Returns results with an ID greater than (that is, more recent than) the specified
ID. There are limits to the number of Tweets which can be accessed through the API. If the
limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID
available.
o max_id = Returns results with an ID less than (that is, older than) or equal to the specified ID.
o count = The number of records to retrieve. Must be less than or equal to 200.
o page = the page of results to retrieve.
Twitter_GetMutes
Twitter_GetMutes(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100))
Twitter_GetRetweetedBy
Twitter_GetRetweetedBy(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100),
AccessToken NVARCHAR(100), AccessTokenSecret NVARCHAR(100), StatusID BIGINT)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 157 of 210
Twitter_GetRetweets
Twitter_GetRetweets(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), StatusID BIGINT, OptionalParameters
Type_HashTable)
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o count = The number of records to retrieve. Must be less than or equal to 100.
Twitter_GetRetweetsOfMe
Twitter_GetRetweetsOfMe(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100),
AccessToken NVARCHAR(100), AccessTokenSecret NVARCHAR(100), OptionalParameters
Type_HashTable)
Returns the 20 most recent tweets of the authenticated user that have recently been retweeted by others.
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o since_id = Returns results with an ID greater than (that is, more recent than) the specified
ID. There are limits to the number of Tweets which can be accessed through the API. If the
limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID
available.
o max_id = Returns results with an ID less than (that is, older than) or equal to the specified ID.
o count = The number of records to retrieve. Must be less than or equal to 100.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 158 of 210
Twitter_GetSentMessages
Twitter_GetSentMessages(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100),
AccessToken NVARCHAR(100), AccessTokenSecret NVARCHAR(100), OptionalParameters
Type_HashTable)
Returns the 20 most recent Direct Messages sent by the authenticating user. You can request up to 200
direct messages per call, up to a maximum of 800 outgoing DMs.
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o since_id = Returns results with an ID greater than (that is, more recent than) the specified
ID. There are limits to the number of Tweets which can be accessed through the API. If the
limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID
available.
o max_id = Returns results with an ID less than (that is, older than) or equal to the specified ID.
o count = The number of records to retrieve. Must be less than or equal to 200.
o page = the page of results to retrieve.
Twitter_GetStatus
Twitter_GetStatus(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), StatusID BIGINT)
Twitter_GetUser
Twitter_GetUser(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), UserIDorScreenName NVARCHAR(20))
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 159 of 210
Twitter_GetUserTimeline
Twitter_GetUserTimeline(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100),
AccessToken NVARCHAR(100), AccessTokenSecret NVARCHAR(100), OptionalParameters
Type_HashTable)
Returns a collection of the most recent Tweets posted by the user indicated by the screen_name or user_id
parameters. User timelines belonging to protected users may only be requested when the authenticated user
either "owns" the timeline or is an approved follower of the owner. The timeline returned is the equivalent of
the one seen when you view a user's profile on twitter.com. This method can only return up to 3,200 of a
user's most recent Tweets.
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o user_id = The ID of the user for whom to return results for.
o screen_name = The screen name of the user for whom to return results for.
o since_id = Returns results with an ID greater than (that is, more recent than) the specified
ID. There are limits to the number of Tweets which can be accessed through the API. If the
limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID
available.
o max_id = Returns results with an ID less than (that is, older than) or equal to the specified ID.
o count = Specifies the number of tweets to try and retrieve, up to a maximum of 200 per
distinct request. The value of count is best thought of as a limit to the number of tweets to
return because suspended or deleted content is removed after the count has been applied.
We include retweets in the count, even if include_rts is not supplied.
o exclude_replies = This parameter will prevent replies from appearing in the returned
timeline. Using exclude_replies with the count parameter will mean you will receive up-to
count tweets — this is because the count parameter retrieves that many tweets before
filtering out retweets and replies.
o include_rts = When set to false, the timeline will strip any native retweets (though they will
still count toward both the maximal length of the timeline and the slice selected by the count
parameter).
EXAMPLE:
DECLARE @ConsumerKey NVARCHAR(100),
@ConsumerSecret NVARCHAR(100),
@AccessToken NVARCHAR(100),
@AccessTokenSecret NVARCHAR(100)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 160 of 210
Twitter_MuteUser
Twitter_MuteUser(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), ScreenName NVARCHAR(20), UserID BIGINT)
NOTES:
ScreenName OR UserID is the user to un-follow
ScreenName OR UserID can be NULL, but not both at the same time
Returns the muted user’s info
If you Mute a user that is currently in the authenticating user’s “Mutes” list, you will get that same
user’s info returned; it will not error.
Twitter_Retweet
Twitter_Retweet(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), StatusID BIGINT)
Retweets a tweet.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 161 of 210
Returns a collection (default = 15) of relevant Tweets matching a specified query. Please note that Twitter's
search service is not meant to be an exhaustive source of Tweets. Not all Tweets will be indexed or made
available via the search interface.
NOTES:
See beginning of Twitter section for example of how to set OptionalParameters
Optional Parameters ARE case-sensitive!
Optional Parameters:
o geocode = Returns tweets by users located within a given radius of the given
latitude/longitude. The location is preferentially taking from the Geotagging API, but will fall
back to their Twitter profile. The parameter value is specified by "latitude,longitude,radius",
where radius units must be specified as either "mi" (miles) or "km" (kilometers) (i.e. 5mi).
o lang = Restricts tweets to the given language, given by an ISO 639-1 code. Language
detection is best-effort.
o locale = Specify the language of the query you are sending (only “ja” is currently effective).
This is intended for language-specific consumers and the default should work in the majority
of cases.
o result_type = Specifies what type of search results you would prefer to receive. The current
default is "mixed". Valid values include:
mixed: Include both popular and real time results in the response.
recent: return only the most recent results in the response
popular: return only the most popular results in the response.
o count = The number of tweets to return. Must be less than or equal to 100. Default = 15.
o until = Returns tweets generated before the given date. Date should be formatted as YYYY-
MM-DD. Keep in mind that the search index may not go back as far as the date you specify
here.
o since_id = Returns results with an ID greater than (that is, more recent than) the specified
ID. There are limits to the number of Tweets which can be accessed. If the limit of Tweets
has occured since the since_id, the since_id will be forced to the oldest ID available.
o max_id = Returns results with an ID less than (that is, older than) or equal to the specified ID.
See the following Twitter page for details on using the Search facility:
o The Search API: https://dev.twitter.com/rest/public/search
o Working with Timelines: https://dev.twitter.com/rest/public/timelines
Twitter_SendDirectMessage
Twitter_SendDirectMessage(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100),
AccessToken NVARCHAR(100), AccessTokenSecret NVARCHAR(100), Message NVARCHAR(140),
Recipient NVARCHAR(20))
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 162 of 210
RETURNS: BIGINT
Sends a Direct Message (private) to the Recipient from the authenticating user and returns the StatusID of
the new message.
Twitter_UnBlockUser
Twitter_UnBlockUser(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), ScreenName NVARCHAR(20))
NOTES:
ScreenName is the user to UnBlock
Returns the unblocked user’s info
If you try to UnBlock a user that is not in the authenticating user’s “Blocks” list, you will NOT get an
error
Twitter_UnFollowUser
Twitter_UnFollowUser(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), ScreenName NVARCHAR(20), UserID BIGINT)
NOTES:
ScreenName OR UserID is the user to un-follow
ScreenName OR UserID can be NULL, but not both at the same time
Returns the un-followed user’s info
If you UnFollow a user that is not currently in the authenticating user’s “Friends” list, you will get the
following error:
“<error>You are not friends with the specified user.</error> ---> System.Net.WebException: The
remote server returned an error: (403) Forbidden.”
Twitter_UnMuteUser
Twitter_UnMuteUser(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100), ScreenName NVARCHAR(20), UserID BIGINT)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 163 of 210
NOTES:
ScreenName OR UserID is the user to un-follow
ScreenName OR UserID can be NULL, but not both at the same time
Returns the un-muted user’s info
If you UnMute a user that is not currently in the authenticating user’s “Mutes” list, you will get an
empty result set returned, but not an error.
Twitter_Update
Twitter_Update(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), AccessToken
NVARCHAR(100), AccessTokenSecret NVARCHAR(100) , Message NVARCHAR(140), InReplyToStatusID
BIGINT, Latitude FLOAT, Longitude FLOAT)
RETURNS: BIGINT
Posts a new Status message for the authenticating user and returns the StatusID of the new message.
NOTES:
InReplyToStatusID is optional. Pass in NULL if the Update is not a reply.
InReplyToStatusID will be ignored unless the author of the Status this parameter references is
@replied within the Status text. Therefore, you must start the Status with @username, where
username is the author of the referenced Status
Latitude and Longitude should both have a value OR both be NULL
This Function is subject to update limits. A HTTP 403 will be returned if this limit as been hit.
Twitter will ignore attempts to perform a duplicate Update. With each Update attempt the application
compares the update text with the authenticating user's last successful update and ignores any
attempts that would result in duplication. Therefore, a user cannot submit the same Status twice in a
row. A duplicate submission will return the StatusID from the previously successful Update if a
duplicate has been silently ignored.
Twitter_xAuth
Twitter_xAuth(ConsumerKey NVARCHAR(100), ConsumerSecret NVARCHAR(100), UserName
NVARCHAR(100), Password NVARCHAR(100))
Uses xAuth to translate a UserName and Password into the AccessToken and AccessTokenSecret for the
specified Application (as identified by the ConsumerKey and ConsumerSecret).
NOTES:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 164 of 210
This will only work if your Application has been granted access to xAuth by Twitter. Most users /
Applications will not need this. If you do need this (to pass in many UserNames and Passwords) then
you need to contact Twitter to request xAuth permission at: [email protected]
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 165 of 210
RunningTotal_Add
RunningTotal_Add(IdentificationLabel NVARCHAR(50), TheValue FLOAT, ResetIndicator
NVARCHAR(4000))
RETURNS: FLOAT
Adds TheValue to a variable that starts at 0 and persists between each row of the result set.
NOTES:
IdentificationLabel:
o This is only needed if you either:
Have more than one Running Total in a query
Need to either pre-seed a value OR need the value once the query is done
o If left blank, a new RunningTotal entry will be created for each run of the query AND it will not
be able to be shared across queries
o If used, be careful to not use a static value as that can be shared between queries in the
same SPID or between queries that reuse a SPID. It is safest to create a
UNIQUEIDENTIFIER using NEWID() and store that in a variable. This will ensure that the
value is unique to that run of the Batch / Stored Proc.
o See also: RunningTotal_Get
TheValue:
o Can be + or –
ResetIndicator:
o If the value of ResetIndicator ever changes from one row to the next, the stored value will be
reset to zero (0).
o This should be used only if wanting to show a running total within a grouping
o If used, it can be set to any field in the query that would change between groups, such as a
group ID or name
o If not used, set to empty string ‘’
At some point you MUST run RunningTotal_ClearCache to clear out the memory or else it will
just keep building up (at least until the SQL Server process is restarted)
EXAMPLES:
SELECT ints.IntVal, SQL#.RunningTotal_Add('', ints.IntVal, '') AS [Total]
FROM SQL#.Util_GenerateInts(0, 11, 1) ints
ORDER BY ints.IntVal ASC
----------
DECLARE @RunningTotalID UNIQUEIDENTIFIER, @Dummy FLOAT
SET @RunningTotalID = NEWID()
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 166 of 210
RunningTotal_CacheSize
RunningTotal_CacheSize(SPID INT)
RETURNS: INT
Gets the current size (in bytes) of the memory used by the Running Total cache.
NOTES:
Pass in @@SPID to get the memory used by the current session only
Pass in 0 to get the total cache size across ALL sessions
EXAMPLE:
SELECT SQL#.RunningTotal_CacheSize(@@SPID) -- 92
SELECT SQL#.RunningTotal_CacheSize(0) -- 213
RunningTotal_ClearCache
RunningTotal_ClearCache(MinutesSinceLastAccess INT)
RETURNS: INT
Removes entries from the Running Total cache that have not been accessed (updated or read) within the
specified amount of minutes.
NOTES:
Pass in 0 to clear all values
Typicallyt, this command should be scheduled via a SQL Agent Job that runs every 30 – 60 minutes
and passes in a value of 30 – 60
Return value is the number of Running Totals that were removed from the cache
This command MUST be run occassionaly in order to reduce the amount of memory taken up by the
Running Total cache as it will remain in memory until this command is called or the SQL Server
service is restarted.
EXAMPLE:
SELECT SQL#.RunningTotal_ClearCache(30)
RunningTotal_Get
RunningTotal_Get(IdentificationLabel NVARCHAR(50))
RETURNS: FLOAT
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 167 of 210
NOTES:
This only works if an IdentificationLabel was used when creating the Running Total
See also: RunningTotal_Add
EXAMPLE:
DECLARE @RunningTotalID UNIQUEIDENTIFIER
SET @RunningTotalID = NEWID()
SELECT SQL#.RunningTotal_Get(@RunningTotalID)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 168 of 210
User-Defined Aggregates
Creating User-Defined Aggregates started in SQL Server 2005. They act just like standard T-SQL
Aggregates (SUM, MIN, MAX, AVG, COUNT) and work over groups of data, typically grouped together via a
GROUP BY.
RETURNS: BIGINT
NOTES:
Returns the result of doing a bitwise AND operation on all values in each group
T-SQL bitwise AND operator = “&”
Like the SUM and AVG aggregates, NULL values are ignored but duplicates count
EXAMPLES:
SELECT 16 & 30 & 24, (16 & 30) & 24, 16 & (30 & 24) -- 16
SELECT tmp.GroupID,
SQL#.Agg_BitwiseAND(tmp.BitVal) AS [AND]
FROM (
SELECT 1, 16
UNION ALL
SELECT 1, 30
UNION ALL
SELECT 1, 24
UNION ALL
SELECT 2, NULL
UNION ALL
SELECT 3, 23
) tmp (GroupID, BitVal)
GROUP BY tmp.GroupID;
GroupID AND
1 16
2 NULL
3 23
RETURNS: BIGINT
NOTES:
Returns the result of doing a bitwise OR operation on all values in each group
T-SQL bitwise OR operator = “|”
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 169 of 210
Like the SUM and AVG aggregates, NULL values are ignored but duplicates count
EXAMPLES:
SELECT 16 | 30 | 24, (16 | 30) | 24, 16 | (30 | 24) -- 30
SELECT tmp.GroupID,
SQL#.Agg_BitwiseOR(tmp.BitVal) AS [OR]
FROM (
SELECT 1, 16
UNION ALL
SELECT 1, 30
UNION ALL
SELECT 1, 24
UNION ALL
SELECT 2, NULL
UNION ALL
SELECT 3, 23
) tmp (GroupID, BitVal)
GROUP BY tmp.GroupID;
GroupID OR
1 30
2 NULL
3 23
RETURNS: BIGINT
NOTES:
Returns the result of doing a bitwise XOR (eXclusive OR) operation on all values in each group
T-SQL bitwise XOR operator = “^”
Like the SUM and AVG aggregates, NULL values are ignored but duplicates count
EXAMPLES:
SELECT 16 ^ 30 ^ 24, (16 ^ 30) ^ 24, 16 ^ (30 ^ 24) -- 22
SELECT tmp.GroupID,
SQL#.Agg_BitwiseXOR(tmp.BitVal) AS [XOR]
FROM (
SELECT 1, 16
UNION ALL
SELECT 1, 30
UNION ALL
SELECT 1, 24
UNION ALL
SELECT 2, NULL
UNION ALL
SELECT 3, 23
) tmp (GroupID, BitVal)
GROUP BY tmp.GroupID;
GroupID XOR
1 22
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 170 of 210
2 NULL
3 23
Agg_GeometricAvg
Agg_GeometricAvg(FLOAT)
RETURNS: FLOAT
NOTES:
Returns a geometric average PER GROUP, just like AVG, SUM, etc.
Formula = (Val1 * Val2 * Val3 * Valn)
1/n
Like the SUM and AVG aggregates, NULL values are ignored but duplicates count
For more info, please see: http://en.wikipedia.org/wiki/Geometric_mean
EXAMPLES:
SELECT SQL#.Agg_GeometricAvg(test.col)
FROM (
SELECT 2 AS 'col'
UNION ALL
SELECT 3
UNION ALL
SELECT NULL
UNION ALL
SELECT 4
) test
-- 2.88449914061482
-- same as:
-- (2 * 3 * 4) = 24; POWER(24.0, (1.0/3.0))
SELECT POWER(CONVERT(FLOAT, 24), (CONVERT(FLOAT, 1)/3))
-- 2.88449914061482
RETURNS: FLOAT
NOTES:
Returns the Harmonic Mean PER GROUP, just like AVG, SUM, etc.
Formula = n / (1/X1 + 1/X2 + ...1/Xn)
Like the SUM and AVG aggregates, NULL values are ignored but duplicates count
For more info, please see: http://en.wikipedia.org/wiki/Harmonic_mean
EXAMPLES:
SELECT (1/1 + 1/2.0 + 1/4.0), 3.0 / (1/1 + 1/2.0 + 1/4.0), 12.0/7.0
-- 1.750000 1.71428571428571428571 1.714285
SELECT 4, 1
UNION ALL
SELECT 72, 2 -- Group 2 is a single value
UNION ALL
SELECT 4, 3 -- Group 3 has a NULL and a value
UNION ALL
SELECT NULL, 3
UNION ALL
SELECT NULL, 4 -- Group 4 is just a NULL
) tmp (val, GroupID)
GROUP BY tmp.GroupID;
GroupID HarmonicMean
1 1.71428571428571
2 72
3 4
4 NULL
Agg_Join
Agg_Join(NVARCHAR(4000))
RETURNS: NVARCHAR(MAX)
NOTES:
Produces a comma-separated list of values in the group
This accomplishes the same thing as String_Join() but over a group rather than over various rows
Unlike String_Join(), this Agg_Join() does not have the option to ignore empty value
Like COUNT(*), NULL values and duplicate values are included
Datasets that are over 8000 characters when combined (and including however many commas are
needed to separate the values) will work to varying degrees based on how well the data compresses
in memory.
EXAMPLES:
SELECT SQL#.Agg_Join(ROUTINE_NAME) FROM INFORMATION_SCHEMA.ROUTINES
-- File_GetTempPath,File_PathExists,File_WriteFile,File_GetFile,...
RETURNS: NVARCHAR(MAX)
NOTES:
This is NOT available on SQL Server 2005 instances!
This UDA is located in the [SQL#.TypesAndAggregatesPlus] assembly (which will not be present
when installing into a SQL Server 2005 instance)
Produces a comma-separated list of values in the group
Like Agg_Join, this operation is similiar to String_Join but over a group rather than over various rows.
Unlike Agg_Join, this “Plus” version allows for customization:
o Custom delimiter
o If specified, custom first and/or last delimiter
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 172 of 210
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 173 of 210
o Default value (if set to NULL) = {no replacement} (i.e. keep as NULL and get filtered out)
RemoveEmptyEntries BIT
o If enabled, removes any string that is empty / ‘’
o No trimming is performed so a value that has a single space is not considered empty. If you
need trimming then wrap the expression in an LTRIM()
o Removal of empty entries, if enabled, occurs after Null Replacement but before removing
duplicates.
o Default value (if set to NULL) = 0 = {no removal} (i.e. empty string are allowed)
DuplicateHandling TINYINT
o If not set to 0, removes duplicates as determined by the value specified for this option
o Values:
0 = none / disabled / allow duplicates
1 = Remove Case Insensitive duplicates (“A”, “A”, “a”, “a” -> “A” or “a”)
2 = Remove Case Sensitive duplicates (“A”, “A”, “a”, “a” -> “A”, “a”)
o Default value (if set to NULL) = 0 = {none} (i.e. allow duplicates)
UseCompression BIT
o Determines whether or not to compress the data stored in memory as rows are being
processed within the groups.
o Compression was originally added to assist prior to SQL Server 2008 since SQL Server 2005
only allowed for 8000 bytes of memory and hence needed to fit more into that space.
o Compression is less of an issue starting with SQL Server 2008 as the memory space is now
essentially VARBINARY(MAX) instead of VARBINARY(8000)
o If joined strings are somewhat small and/or memory is plentiful, then try setting to 0 (i.e.
disabling).
o When joining larger strings, or large sets of small to medium size strings and/or memory is
less plentiful than extra CPU cycles, then keep as NULL or set to 1 (i.e. enable)
o Default value (if set to NULL) = 1 (i.e. use compression; err on the side of preserving RAM)
EXAMPLES:
-- Get tables with column list (columns order by Ordinal Position)
SELECT
tab.TABLE_SCHEMA,
tab.TABLE_NAME,
SQL#.Agg_JoinPlus(col.COLUMN_NAME, N', ',
RIGHT(N'00' + CONVERT(NVARCHAR(5), col.ORDINAL_POSITION), 2), 1,
NULL, NULL, NULL, NULL,
NULL, 0, 0, NULL) AS [ColumnsInTable]
FROM [msdb].INFORMATION_SCHEMA.TABLES tab
INNER JOIN [msdb].INFORMATION_SCHEMA.COLUMNS col
ON tab.TABLE_NAME = col.TABLE_NAME
AND tab.TABLE_SCHEMA = col.TABLE_SCHEMA
WHERE tab.TABLE_TYPE = N'BASE TABLE'
GROUP BY tab.TABLE_SCHEMA, tab.TABLE_NAME
ORDER BY tab.TABLE_SCHEMA ASC, tab.TABLE_NAME ASC;
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 174 of 210
Agg_Median
Agg_Median(FLOAT)
RETURNS: FLOAT
NOTES:
Returns the middle value (or average of the two middle values in an even-numbered grouping) PER
GROUP, just like COUNT, etc.
Like the SUM and AVG aggregates, NULL values are ignored but duplicates count
Uses compression to work over a greater amount of values than is possible natively. Natively max
number of values is 999 but with compression can be several thousand depending on the values and
what order they are in
EXAMPLES:
SELECT SQL#.Agg_Median(test.col)
FROM (
SELECT 2 AS 'col'
UNION ALL
SELECT 3
UNION ALL
SELECT NULL
UNION ALL
SELECT 100
) test
-- 3
SELECT SQL#.Agg_Median(test.col)
FROM (
SELECT 2 AS 'col'
UNION ALL
SELECT 3
UNION ALL
SELECT 76
UNION ALL
SELECT 100
) test
-- 39.5
Agg_Random
Agg_Random(FLOAT)
RETURNS: FLOAT
NOTES:
Returns a random value from within the grouping
Like the SUM and AVG aggregates, NULL values are ignored but duplicates count
Uses compression to work over a greater amount of values than is possible natively. Natively max
number of values is 999 but with compression can be several thousand depending on the values and
what order they are in
If you use more than once in a single statement, all uses of Agg_Random will pick from the same
random row in the set; it will not mix and match random values from different rows
EXAMPLES:
SELECT SQL#.Agg_Random(tab.ValOne), SQL#.Agg_Random(tab.ValTwo)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 175 of 210
FROM (
SELECT 1 AS 'ValOne', 100 AS 'ValTwo'
UNION ALL
SELECT 2, 200
UNION ALL
SELECT 2, 200
UNION ALL
SELECT NULL, NULL
UNION ALL
SELECT 3, 300
) tab
Agg_RootMeanSqr
Agg_RootMeanSqr(FLOAT)
RETURNS: FLOAT
NOTES:
Returns the Root Mean Square (RMS) PER GROUP, just like AVG, SUM, etc.
Formula = SQRT( (X1 + X2 + X3 + Xn ) / n)
2 2 2 2
Like the SUM and AVG aggregates, NULL values are ignored but duplicates count
EXAMPLES:
SELECT SQL#.Agg_RootMeanSqr(test.col)
FROM (
SELECT 2 AS 'col'
UNION ALL
SELECT 3
UNION ALL
SELECT NULL
UNION ALL
SELECT 10
) test
-- 6.13731754650732
-- same as:
-- (POWER(2, 2) + POWER(3, 2) + POWER(10, 2)) = 113; SQRT(113 / 3)
SELECT SQRT(CONVERT(FLOAT, 113) / 3)
-- 6.13731754650732
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 176 of 210
User-Defined Types
Creating User-Defined Types started in SQL Server 2005. They act just like standard T-SQL datatypes: they
can be used for local variables, they can be used as parameters for Stored Procedures and User-Defined
Functions, and they can even be used as columns in tables to be persisted. Regarding persisting in a table,
however, it is advised that if this functionality is desired then to instead persist the ToString() output as that
can be used as direct input to initialize each Type. The reason for not wanting to persist these in actual tables
is the fact that the CLR assembly that contains the definition for the persisted User-Defined Type is then
required to exist until the User-Defined Type’s are no longer in use (i.e. persisted). This would have the effect
of making it impossible to upgrade SQL# or whatever other CLR Assembly holds the persisted type.
However, these User-Defined Types are perfect for use with Temp Tables and even Table Variables. The
main value in these User-Defined Types is the ability to work with sets of data that are not a Temp Table that
has an IDENTITY column that many people use to move away from Cursors. Also, they provide a very easy
mechanism for transferring sets of data between Stored-Procedures or User-Defined Functions that is
currently only possible with Temp Tables, but Temp Tables need to exist physically, even if only temporarily,
in TempDB which can cause additional I/O contention that can lead to blocking or slowing down of other
queries or processes on the server that require disk I/O.
User-Defined Types reside in the SQL#.TypesAndAggregates assembly. This assembly is required by the
following assemblies: SQL#.Twitterizer and SQL#.Network. This assembly should be able to remain in SAFE
mode even if assemblies that require it are set to EXTERNAL_ACCESS or UNRESTRICTED.
Type_FloatArray
DECLARE @Variable SQL#.Type_FloatArray
CONSTRUCTOR:
Comma-separated list of numbers (INT or FLOAT)
Spaces are trimmed on both sides before converting values to real numbers
SET @Type_FloatArrayVariable = ‘’
SET @Type_FloatArrayVariable = ‘1,34,34,98,453’
SET @Type_FloatArrayVariable = ‘.02342 , 5675.4564’
PROPERTIES:
Count
The number of items in the Array
METHODS:
AddData(@Index INT, @InputStrings NVARCHAR(4000))
RETURNS: Type_FloatArray
Adds one or more FLOATS, separated by commas (like the Constructor)
@Index is where to insert the new values
@Index = 0 will ADD to the end of the Array
@Index > 1 will INSERT at the @Index point
@Index > FloatArray.Count or < 0 will cause an error
Avg()
RETURNS: FLOAT
Returns the average of all of the items
zero-value items do count
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 177 of 210
Clear()
RETURNS: Type_FloatArray
Removes ALL items from the Array, leaving the Count = 0
ContainsItem(@SearchFloat FLOAT)
RETURNS: BIT
Will return 1 (true) if the @SearchFloat is found anywhere in the array
GetAt(@Index INT)
RETURNS: FLOAT
Returns the value found at the @Index
@Index < 0 will cause an error
@Index > FloatArray.Count returns NULL
Median()
RETURNS: FLOAT
Returns the middle value or the average of the two middle values in an even-numbered array
0 values do count
RemoveAt(@Index INT)
RETURNS: Type_FloatArray
Removes the value at @Index
@Index < 1 or > FloatArray.Count will cause an error
RemoveItem(@InputFloat FLOAT)
RETURNS: Type_FloatArray
Removes the first occurance of @InputFloat found in the array
Reverse()
RETURNS: Type_FloatArray
Reverses the order of the items in the array
This is in essence a DESCending sort by index, not by value
Sort()
RETURNS: Type_FloatArray
This does an ASCending sort of the values by value, not by index
If you want a DESCending sort of the values, call Reverse() after Sort()
Sum()
RETURNS: FLOAT
Returns a sum of the values
ToString()
RETURNS: NVARCHAR(4000)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 178 of 210
NOTES:
Is a 1-based indexed array of FLOATs
Must be initialized with constructor (=) before using (at least set to = ‘’)
NULLs (or empty strings or empty values between commas) are NOT allowed
Property and Method names ARE case-sensitive: Array.Avg() <> Array.AVG()
Uses compression to work over a greater amount of values than is possible natively. Natively max
number of values is 999 but with compression can be several thousand depending on the values and
what order they are in
EXAMPLE #1:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 179 of 210
EXAMPLE #2:
SET @Customers = @Customers.Sort() -- just to show sorting; WHILE loop works the
same
WHILE (@Customers.Count > 0)
BEGIN
PRINT 'Working on CustomerID: ' + CONVERT(VARCHAR, @Customers.GetAt(1))
/* EXEC Schema.Proc @Customers.GetAt(1) */
/*
Working on CustomerID: 15696
Working on CustomerID: 11706
Working on CustomerID: 10590
Working on CustomerID: 9998
Working on CustomerID: 337
Working on CustomerID: 11483
Working on CustomerID: 2695
Working on CustomerID: 4144
Working on CustomerID: 10970
Working on CustomerID: 16201
-- or --
Working on CustomerID: 337
Working on CustomerID: 2695
Working on CustomerID: 4144
Working on CustomerID: 9998
Working on CustomerID: 10590
Working on CustomerID: 10970
Working on CustomerID: 11483
Working on CustomerID: 11706
Working on CustomerID: 15696
Working on CustomerID: 16201
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 180 of 210
*/
Type_HashTable
DECLARE @Variable SQL#.Type_HashTable
CONSTRUCTOR:
Ampersand (&)-separated list of Key=Value pairs OR empty string (‘’)
Both Key and Value are NVARCHAR(4000)
SET @Type_HashTableVar = ‘’
SET @Type_HashTableVar = ‘NC=North Carolina’
SET @Type_HashTableVar = ‘City=Chicago&State=IL&Zipcode=60647’
PROPERTIES:
Count
The number of items in the Array
ValuesDataLength
The total number of characters of all of the “Values” combined
METHODS:
AddData(InputPairs NVARCHAR(4000))
RETURNS: Type_HashTable
Adds one or more Key=Value pairs, separated by ampersands (&) (like the Constructor)
Clear()
RETURNS: Type_HashTable
Removes ALL items from the HashTable, leaving the Count = 0
ContainsKey(@SearchString NVARCHAR(4000))
RETURNS: BIT
Returns 1 (true) if @SearchString is found at all amongst the Keys
@SearchString only matches whole-word and is case-sensitive
ContainsValue(@SearchString NVARCHAR(4000))
RETURNS: BIT
Returns 1 (true) if @SearchString is found at all amongst the Values
@SearchString only matches whole-word and is case-sensitive
GetValue(@Key NVARCHAR(4000))
RETURNS: NVARCHAR(4000)
Returns the Value identified by the @Key
@Key only matches whole-word and is case-sensitive
If @Key is not found, NULL is returned
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 181 of 210
Returns the Value identified by the @Key matching the Regular Expression (RegEx) of
@SearchPattern which can be set to @CaseSensitive or not
@SearchPattern can match non-whole-word Keys and is not necessarily Case-Sensitive
If @SearchPattern matches more than one Key, the first match is used
RemovePair(@InputKey NVARCHAR(4000))
RETURNS: Type_HashTable
Removes the Key=Value pair identified by the @Key
@Key only matches whole-word and case-sensitive
ToString()
RETURNS: NVARCHAR(4000)
Returns an Ampersand (&)-separated list of Key=Value pairs
If wanting to persist the value of the HashTable, store the ToString() value and then use that value
with the Constructor or AddData().
NOTES:
Is a key/value pair array
Must be initialized with constructor (=) before using (at least set to = ‘’)
The order of the Keys does not matter
Key may be an empty string (nothing to the left of the =) but in all cases the Keys must be unique (so
only one empty / blank Key can be added)
Values can also be empty but do NOT need to be unique
Property and Method names ARE case-sensitive: Clear() <> CLEAR()
Uses compression to work over a greater amount of values than is possible natively. Natively max
number of values is based on all keys and values adding up to 7996 bytes but with compression can
be tens of thousands of bytes depending on the values and what order they are in
EXAMPLES:
DECLARE @HashVar SQL#.Type_HashTable
Type_NVarcharArray
DECLARE @Varible Type_NVarcharArray
CONSTRUCTOR:
Comma-separated list of strings (VARCHAR or NVARCHAR)
Spaces are trimmed on both sides
SET @Type_NVarcharArrayVariable = ‘’
SET @Type_NVarcharArrayVariable = ‘Hello’
SET @Type_NVarcharArrayVariable = ‘One,Two , Three’
PROPERTIES:
Count
The number of items in the Array
DataLength
The total number of characters of all of the Items combined
METHODS:
AddData(@Index INT, @InputStrings NVARCHAR(4000))
RETURNS: Type_NVarcharArray
Adds one or more Strings (VARCHAR or NVARCHAR), separated by commas (like the Constructor)
@Index is where to insert the new values
@Index = 0 will ADD to the end of the Array
@Index > 1 will INSERT at the @Index point
@Index > NVarcharArray.Count or < 0 will cause an error
Clear()
RETURNS: Type_NVarcharArray
Removes ALL items from the Array, leaving the Count = 0
ContainsItem(@SearchString NVARCHAR(4000))
RETURNS: BIT
Will return 1 (true) if the @SearchString is found anywhere in the array
@SearchString matches only on whole-words and is case-sensitive
GetAt(@Index INT)
RETURNS: NVARCHAR(4000)
Returns the String found at the @Index
@Index < 0 will cause an error
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 183 of 210
RemoveAt(@Index INT)
RETURNS: Type_NVarcharArray
Removes the String at @Index
@Index < 1 or > NVarcharArray.Count will cause an error
RemoveItem(@InputString NVARCHAR(4000))
RETURNS: Type_NVarcharArray
Removes the first occurrence of @InputString found in the array
Reverse()
RETURNS: Type_NVarcharArray
Reverses the order of the Strings in the array
This is in essence a DESCending sort by Index, not by String
Sort()
RETURNS: Type_NVarcharArray
This does an ASCending sort of the Strings by value, not by index
If you want a DESCending sort of the values, call Reverse() after Sort()
ToString()
RETURNS: NVARCHAR(4000)
Returns a comma-separated list of the String values
If wanting to persist the value of the NVarcharArray, store the ToString() value and then use that
value with the Constructor or AddData().
NOTES:
Is a 1-based indexed array of NVARCHAR(4000)s
Must be initialized with constructor (=) before using (at least set to = ‘’)
NULLs (or empty strings or empty values between commas) ARE allowed
Property and Method names ARE case-sensitive: Sort() <> SORT()
NVarcharArray Properties and Methods work just like matching Properties and Methods of FloatArray
and HashTable; see previous examples of FloatArray and HashTable to better understand how
NVarcharArray works
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 184 of 210
Uses compression to work over a greater amount of values than is possible natively. Natively max
number of values is based on all values adding up to 7996 bytes but with compression can be tens of
thousands of bytes depending on the values and what order they are in
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 185 of 210
History
th
Version 1.0.2 (June 25 , 2006 – Initial Release)
th
Version 1.1.4 (October 20 , 2006)
Free Version
Removed: all INET functions and SQLsharp_Update
Added: Math_RandomRange
Changed:
o Bug in Phnx_ToWords returned Negative Zero for -1
o Added Lower and Upper bounds checking in Phnx_ToWords
o Changed return datatype in Math_IsPrime to BIT from INT
o Added StepTypes of Quarter and Week to Phnx_GenerateDateTimes and
Phnx_GenerateDateTimeRange
o Added abbreviations for StepTypes as paralleled in Books Online under DATEADD and
DATEDIFF functions (ex: year = yyyy, yy)
th
Version 1.1.5 (October 20 , 2006)
Paid-for Version
Includes all functions
Same as Version 1.1.4 except it includes all INET functions and SQLsharp_Update
th
Version 1.5.6 and 1.5.7 (February, 16 , 2007)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 186 of 210
th
Version 2.0.8 and 2.0.9 (March 18 , 2007)
th
Version 2.1.10 and 2.1.11 (July 16 , 2007)
th
Version 2.2.12 and 2.2.13 (August 19 , 2007)
th
Version 2.3.16 and 2.3.17 (September 10 , 2007)
Fixed Constructor method for all three User-Defined Types (FloatArray, HashTable, and
NVarcharArray); allow for empty string (‘’) to be passed in to initialize the Type as empty.
Fixed Math_CompoundAmortizationSchedule: adjusted final payment calculation and minor issues
with rounding
th
Version 2.4.18 and 2.4.19 (October 14 , 2007)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 187 of 210
th
Version 2.5.20 and 2.5.21 (November 18 , 2007)
th
Version 2.6.22 and 2.6.23 (May 18 , 2008)
th
Version 2.7.24 and 2.7.25 (August 5 , 2008)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 188 of 210
th st
Version 2.8.28 and 2.8.29 / 2.8.30 and 2.8.31(May 27 and 31 , 2009)
Updated SQL# Installer to not cause the “file has an extremely long line” warning message when
opening in Management Studio (SSMS)
Renamed main Assembly from [SQLsharp] to [SQL#].
Added two new Assemblies: [SQL#.OS] and [SQL#.Twitterizer]
Fixed potential memory leak in INET_GetWebPages
Fixed output of Table-Valued Functions to be properly streaming
Increased width of NVARCHAR fields in the result sets of File functions
Fixed RegEx functions to not error if the ExpressionToValidate is an empty string
Compiled RegEx patterns in Util_IsValid* functions for faster execution
Updated SQLsharp_Setup, SQLsharp_Uninstall, and the installation scripts to allow SQL# to be
installed into a user-defined Schema and then handle being uninstalled from that Schema. In order to
install into a Schema other than “SQL#” just change the value of the @SQLsharpSchema variable.
Added RegExOptionsList parameter to all RegEx Functions
Added TrapErrorInline BIT parameter to INET_GetWebPages Function to control whether HTTP
errors (e.g. 404, 500, etc.) throw an exception or get returned in the result set. Please note that this
is a Function signature change that breaks existing uses of the Function since existing calls will not
rd
have the new parameter. Passing in NULL (or 0) as the 3 parameter will cause the Function to work
the same as it did previously.
Added optional @AssemblyName NVARCHAR(4000) input parameter to SQLsharp_SetSecurity so
that the various SQL# Assemblies can be dealt with individually.
Added DB Procs: BulkCopy (suggested and tested by DM Unseen [Martijn Evers]) and ForEach
Added INET Function: URIEncodeData
Added new OS group (SQL#.OS Assembly)
Added OS Functions: EventLogRead, EventLogWrite, ProcessStart, ProcessGetInfo, ProcessKill,
GenerateTone, MachineName, and Uptime
Added new Twitter group (SQL#.Twitterizer Assembly)
Added Twitter Functions (via Twitterizer library): Update, DestroyMessage, SendDirectMessage,
GetSentMessages, GetMessages, GetFriendsTimeline, GetPublicTimeline, GetUserTimeline, and
GetReplies
th
Version 2.8.32 and 2.8.33 (June 6 , 2009)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 189 of 210
st
Version 2.9.39 and 2.9.40 (November 1 , 2009)
Added Convert functions: HtmlToXml (suggested by Mitch Schroeter), UUDecode, and UUEncode
Added Twitter functions: DestroyDirectMessage, FollowUser, GetFollowers, GetFriends,
GetMentions, GetStatus, GetUser, UnFollowUser
Added Date function: NthOccurrenceOfWeekday
Updated File_SplitIntoFields: Changed SkipFirstRow BIT into RowsToSkip INT and fixed potential
memory leak. The parameter change is non-breaking as the BIT values of 0 and 1 (representing to
not skip any rows and to skip the first row respectively) directly map to the new behavior of how many
rows to skip with 0 still meaning not to skip any and 1 meaning to skip 1 row which is the same result
as SkipFirstRow = 1. (suggested by Andy Krafft)
Updated Twitter functions so that StatusID is now a BIGINT instead of INT: DestroyStatus,
GetFriendsTimeline, GetMessages, GetPublicTimeline, GetReplies, GetSentMessages,
GetUserTimeline, SendDirectMessage, and Update
Added INET functions: URIGetInfo (suggested by Mitch Schroeter) and URIGetLeftPart
Updated Type_HashTable: added AddItem(@InputKey NVARCHAR(4000), @InputValue
NVARCHAR(4000)) method / function.
Updated DB_BulkExport: Added @AppendFile BIT = 0, @RowsExported INT = -1 OUTPUT
parameters. This should be a non-breaking change since the two new parameters have defaults.
Therefore, existing implementations do not need to change.
Updated INET_FTPGetFile: Changed @OverwriteExistingFile BIT parameter to be @FileHandling
TINYINT (2 = Incremental / Restart). This is a non-breaking change since the old parameter BIT
values of 0 and 1 directly map (i.e. implicitly convert) to the new parameter datatype of TINYINT and
which cause the same behavior. Therefore, existing implementations do not need to change.
(suggested by Andy Krafft)
BREAKING CHANGE : Updated INET_FTPGet and INET_FTPGetBinary: Added @ContentOffset
BIGINT parameter to support Incremental downloads / resuming. (suggested by Andy Krafft)
BREAKING CHANGE : Updated INET_GetWebPages: Added four new fields to the result set
(IsFromCache, LastModified, StatusCode, StatusDescription) and added three new input parameters
(@MaximumAutomaticRedirections, @Timeout, @MaximumResponseHeadersLength,
@CustomHeaders)
IMPORTANT NOTE: Deprecated Twitter_DestroyMessage and replaced with Twitter_DestroyStatus.
It is just a rename as the functionality is the same. Currently DestroyMessage points to
DestroyStatus, however, please convert all references to DestroyMessage as it will be removed in the
next version.
Thanks to Mitch Schroeter for the suggestion of adding the MaximumResponseHeadersLength,
CustomHeaders, and Method parameters to INET_GetWebPages
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 190 of 210
th
Version 2.10.43 and 2.10.44 (January 20 , 2010)
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 191 of 210
th
Version 2.11.51 and 2.11.52 (June 19 , 2010)
th
Version 2.12.53 and 2.12.54 (September 19 , 2010)
This release (2.12.x) is a Twitter API ONLY update. No other changes have been made in this
release! If you do not use the Twitter functions and are on 2.11.x you do NOT need to upgrade.
However, if you are using the Twitter functions then you MUST upgrade to 2.12.x for the full
OAuth implementation changes! The Twitter functions in version 2.11.x will no longer work as
th
of Monday, October 18 , 2010.
Please see the SQL# Twitter setup guide for details on how to set up your Twitter Application:
http://www.SQLsharp.com/download/SQLsharp_TwitterSetup.pdf
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 192 of 210
nd
Version 2.13.55 and 2.13.56 (November 22 , 2010)
th
Version 2.14.60 and 2.14.61 (March 13 , 2011)
Updated String_IsNumeric to allow for “d” to be double-precision as well as not requiring the + or – for
scientific notation
Added String functions: Replace, SplitKeyValuePairs, TrimChars, TrimEnd, and TrimStart
Updated Twitter Status-related Table-Valued Functions to return 7 geo fields: GetUserTimeline,
GetPublicTimeline, GetFriendsTimeline, GetReplies, GetMentions, GetFavorites, GetMessages, and
GetSentMessages
BREAKING CHANGE : Updated Twitter_Update to accept optional Longitude and Latitude values
for geocoding Tweets
Added Twitter functions: GetHomeTimeline, GetRetweetedBy, GetRetweetedByMe,
GetRetweetedToMe, GetRetweets, GetRetweetsOfMe, and Retweet
BREAKING CHANGE : Updated Twitter Status-related Table-Valued Functions to be able to pass
in Twitter Optional Parameters:GetFriendsTimeline, GetFavorites, GetMentions, GetMessages,
GetReplies, GetSentMessages, and GetUserTimeline as well as new functions GetHomeTimeline,
GetRetweetedBy, GetRetweetedByMe, GetRetweetedToMe, GetRetweets, and GetRetweetsOfMe
Deprecated Twitter_GetReplies in favor of GetMentions.
Updated DB_BulkExport: added support for UTF7 as well as more datatypes: rowversion, date, time,
datetime2, and datetimeoffset
Updated DB_DumpData: added support for UTF7 as well as more datatypes: rowversion, date, time,
datetime2, and datetimeoffset
Updated DB_HTMLExport: added support for UTF7
Added new RunningTotal group (not available in Free version)
Added RunningTotal functions: Add, Get, CacheSize, and ClearCache
Added Util functions: HashBinary and IsValidConvert
Added Date functions: FullDateTimeString (not available in Free version) and NewDateTime
Updated Date_FullDateString and Date_FullTimeString to return NULL if input is NULL rather than
error
Updated FILE functions to allow for full streaming and hence use much less memory: CopyMultiple,
DeleteMultiple, GetDirectoryListing, and MoveMultiple
Updated RegEx_Split to stream results out
Updated Table-Valued RegEx functions to return NVARCHAR(MAX) for [Value] instead of
NVARCHAR(4000): Match, Matches, and Split
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 193 of 210
th
Version 2.16.64 and 2.16.65 (October 19 , 2011)
Fixed error in installer that shows up when the collation setting for tempdb is not the same as the
setting for the database in which SQL# is installed
Fixed minor error with SQLsharp_Uninstall (minor in that the error is reported but the uninstall still
completes) that occurs when the database in which SQL# is installed has a case-sensitive collation
Updated INET_GetIPAddress to return NULL when NULL is passed in rather than error
Added INET function: INET_GetIPAddressList
Updated Date_BusinessDays and Date_IsBusinessDay to include two new holidays: Presidents' Day
[US] (3rd Monday in February) (suggested by Claudio Pracilio) and Columbus Day [traditional]
(October 12th)
Added Date function: Date_BusinessDaysAdd (suggested by Victor Wang)
Added RegEx function: RegEx_CaptureGroups (suggested by Jason Pierce)
Updated Date_BusinessDays to allow for StartDate to be greater than EndDate which will return a
negative number, similar to how DATEDIFF works (suggested by Victor Wang)
Updated Date_BusinessDays to return NULL when any parameter is NULL rather than error
Added String functions: FixedWidthIndex (suggested by Don Folino) and FixedWidthSplit
th
Version 2.17.68 and 2.17.69 (May 6 , 2012)
Added Math functions: FormatDecimal, FormatFloat (not available in Free version), and
FormatInteger (not available in Free version)
Add / Remove assemblies:
o Ability to install / uninstall individual assemblies. This is not automated yet but will someday
soon be incorporated into the installer script.
o Updated SQLsharp_Setup to accept new parameter @SQLsharpAssembly, which if
specified, will install the wrapper functions and stored procedures for only the specified
assembly. The specified assembly needs to already exist.
o Updated SQLsharp_Uninstall to accept new parameter @SQLsharpAssembly so that the
specified assembly and its wrapper functions and stored procedures can be uninstalled
without affecting anything else.
Security:
o SQL#-specific database login created from asymmetric key.
o All SQL# assemblies now owned / authorized by new SQL# login instead of dbo.
o Updated SQLsharp_SetSecurity to no longer set the DB to TRUSTWORTHY ON when
setting an assembly to level 2 or 3 (External Access or Unrestricted).
o All assemblies can be disallowed from being set to either Unrestricted (but allowed for
External Access) or both Unrestricted and External Access.
o Most functionality requiring External Access for main SQL# assembly has been broken out
into separate assemblies: SQL#.DB, SQL#.FileSystem (FILE_* functions), and
SQL#.Network (INET_* functions). Not only does SQL# stay as Safe, but if only INET_*
functions are being used and not FILE_*, then no need to set SQL#.FileSystem to External
Access.
o If you are upgrading from a pre-3.0.x version and had any of the assemblies’ permissions set
to level 2 or 3 (External Access or Unrestricted), then the database where SQL# is installed
had its TRUSTWORTHY setting set to ON and this might not be necessary anymore. SQL#
no longer requires TRUSTWORTHY to be set to ON for External Access or Unrestricted
assemblies and if you have no other need for it to be on then please run the following:
ALTER DATABASE [{database_where_SQL#_exists}] SET TRUSTWORTHY OFF
o If you don’t want any of the assemblies to ever be set to Unrestricted (but still be eligible to be
set to External Access), then set the @AllowUnrestrictedAccess variable towards the top of
the install script to 0. If you don’t want any of the assemblies to ever be set to either External
Access or Unrestricted, then set both @AllowUnrestrictedAccess and @AllowExternalAccess
variables to 0. Please note that the ability to restrict the level of permissions for any
assembly requires that the database have its TRUSTWORTHY setting set to 0 / OFF.
Installer:
o Uninstall of exisiting SQL# (if it exists) and install of current version now wrapped in a
transaction that will rollback if any problem occurs, leaving everything as it was before the
install attempt if the install cannot complete successfully.
o A login, based on an asymmetric key, is created as a means of allowing assemblies to be set
to External Access or Unrestricted without the need for the database to have
TRUSTWORTHY set to ON.
o A user is created in the database where SQL# is being installed, based on the new login
mentioned just above. This user will own the SQL# assemblies instead of “dbo”.
o New assemblies: SQL#.DB, SQL#.FileSystem (FILE_* functions), SQL#.JsonFx (needed for
Twitter_* functions), SQL#.Network (INET_* functions), and SQL#.TypesAndAggregates.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 195 of 210
o Variables towards the top of the install script allow for easy configuration of new SQL# login
name and permissions.
o If upgrading from a version prior to 3.0.x and the SQL# assembly was set to either External
Access (2) or Unrestricted (3), then several of the new assemblies will be set to that same
permission level to have no initial change in behavior. Those new assemblies are: SQL#.DB,
SQL#.FileSystem, and SQL#.Network.
Twitter:
o Updated to use newer Twitter v1.1 JSON API instead of older v1.0 XML API (v1.0 API starts
th
incremental end-of-life process on March 5 , 2013).
o Requires SQL#.JsonFx and SQL#.TypesAndAggregates assemblies.
o BREAKING CHANGE : Removed functions Twitter_GetRetweetedToMe and
Twitter_GetRetweetedByMe as there is no replacement for either in the v1.1 API.
o BREAKING CHANGE : Removed function Twitter_GetPublicTimeline as there is no exact
replacement in the v1.1 API, but might replace with new “sample” call that is similar.
o BREAKING CHANGE : Removed function Twitter_GetReplies as it was deprecated a while
ago and merely pointed to Twitter_GetMentions.
o BREAKING CHANGE : Removed function Twitter_GetFriendsTimeline as it does not exist
in the v1.1 API and Twitter_GetHomeTimeline is nearly identical.
o Added function: Twitter_SearchTweets (not available in Free version).
o SQL Server 2005 requires Unrestricted access (level 3) for both SQL#.JsonFx and
SQL#.Twitterizer. This is handled automatically in the installer. Also, it is possible that this is
not required in SQL Server 2005 Enterprise Edition, but I have no easy way to verify that at
the moment.
o No signature changes in this release! All input parameters and output fields are the same to
make upgrading a smoother process. BUT, in the very near future there will be at least a few
changes:
UserIDs are now BIGINT at Twitter and the SQL# Twitter functions will be updated to
reflect that in both input params and result set fields and scalar return values.
Most User-based table-valued functions (i.e. those returning a list of users) allow for
paging through the list of results but only getting a max of 20 or 100 at a time,
depending on the call. The SQL# Twitter functions will be updated to return the
“previous” and “next” cursor values so that they can be sent in as Optional
Parameters.
Twitter functions that currently do not have the @OptionalParameters input
parameter where the Twitter call supports optional parameters will have the
@OptionalParameters input parameter added to the signature. These include:
Update, GetFollowers, GetBlocks, and GetFriends.
Those marked with (*) are available in the Free version; the rest are only available in the Full version.
Improved
Date_FormatTimeSpan: each TimeSpanPart can now include an optional width that will be left-
padded with zeros if the actual value of that TimeSpanPart has fewer digits than the specified desired
width. (suggested by Dave Sumlin)
All Twitter functions: helpful error message displayed if SQL#.Twitterizer assembly permission level
is not set to 2
File_GetDirectoryListing: added new [ErrorMessage] field to result set. If the process does not have
permission to list the contents of a directory when doing recursive, the specific error will be noted in
the new field and the process will continue with the next directory; previously the process would error
if permission was denied on any folder.
INET_GetWebPages:
o Added new [ResponseHeaders] XML field to result set (suggested by Dave Sumlin)
o Allow "Referer" to be sent in for CustomHeaders (sets the HTTP_REFERER header)
Fixed
Improved
SQLsharp_Setup (only used by installer script): better error handling and more verbose output.
Date_BusinessDays, Date_BusinessDaysAdd, and Date_IsBusinessDay: added 3 options for
th
Veterans Day (November 11 ) to Holidays list (suggested by David Sumlin)
Type_FloatArray, Type_HashTable, and Type_NVarcharArray: updated AddData / AddItem methods
so that they can be called without first initializing the variable via SET @TypeVar = '';
RegEx_Replace: @RegularExpression of NULL returns NULL instead of erroring
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 197 of 210
DB_BulkExport:
o NULL or empty sting value for @Query exits instead of erroring
o Added defaults for most input parameters
o Changed @Query input param from NVARCHAR(4000) to NVARCHAR(MAX)
o Added input param for @ConnectionString NVARCHAR(500); default = "Context Connection
= true;" (i.e. internal / in-process connection)
o Added input param for @TextQualifierEscape (for embedded TextQualifiers); default = NULL;
NULL = @TextQualifier.
File_GetFile:
o Stream rows from file to SQL Server when setting @SplitLines = 1 rather than reading the
entire contents of the file into memory first.
o Added “LineLength BIGINT” field to the result set that is the number of characters (excluding
newlines / returns) per each line OR all characters (including newlines / returns), if
@SplitLines = 0.
o Changed “ContentLength” field to be cumulative number of characters (excluding newlines /
returns) read so far, inclusive of the current line OR all characters (including newlines /
returns), if @SplitLines = 0.
Fixed
Math_Factorial: passing in 0 returns 1 instead of 0.
INET_GetWebPages: does not error when setting @SplitLines to 1 (issue from the previous release)
Improved
SQLsharp_Setup (only used by installer script) and the installer script: Updated all "SYSNAME"
references to be "sysname" to better support case-sensitive servers as "sysname" is an alias that
needs to be looked-up in the [master] database.
Date_BusinessDays, Date_BusinessDaysAdd, and Date_IsBusinessDay:
th st
o Added 2 holidays—Christmas Eve (December 24 ) and New Year's Eve (December 31 )—to
Holidays list
o Changed @ExcludeDaysMask input param to BIGINT from INT
DB_BulkCopy: Added optional BIGINT OUTPUT param for @RowsCopied that is the number of rows
inserted into the Destination Table (suggested by David Sumlin)
DB_GetQueryInfo:
o Added input param @QueryGroup NVARCHAR(100) to more easily group repeated tests /
makes aggregations to find averages very easy. Default = empty string.
o Added input param @CaptureExecutionPlans BIT to disable logging of execution plans. they
can be large and if testing a loop, each query within each iteration will have its own plan.
Default = "true" / 1.
o Reduced memory consumption
DB_CreateOrAlterQueryInfoTables:
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 198 of 210
Fixed
INET_GetWebPages: Properly encodes XML special characters for ResponseHeaders field to
prevent "&" from causing an error.
DB_DescribeResultSets: No longer errors on SQL 2005, 2008, and 2008 R2 if there was no row
available for sample data.
Math_Convert:
o Returns NULL if any input parameter is NULL rather than erroring
o Improved accuracy for Computer/Digital Storage (will finish temperature and distance
conversions in the next release)
Several Assemblies have code that requires a different security level than other code in that same
Assembly. For example, the SQL#.Network Assembly has some code that can run in SAFE (Level 1)
mode, while most of it requires EXTERNAL_ACCESS (Level 2). Using the code that requires
EXTERNAL_ACCESS forces the code that can run in SAFE to be in an Assembly marked as
EXTERNAL_ACCESS.
Ideally, code will never be given a higher security level than it needs. The goal here is to have as
much code as possible remain in Assemblies that will only ever be marked as SAFE (Level 1). And
then, code requiring EXTERNAL_ACCESS (Level 2) shouldn’t be in an Assembly marked as
UNSAFE. In order to accomplish this, code in each Assembly that requires a higher security level
needs to be moved into a separate Assembly for just that security level. Assemblies will be named
the same as the current category, but with a number at the end indiciating what security level they will
need.
This release has one new Assembly, SQL#_2, that is just the functionality from the SQL# Assembly
that needs security level 2. In the next release, the rest of the Assemblies will be broken out into 1 or
2 additional Assemblies.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 199 of 210
In prior versions it was possible to disable installation of most Assemblies, as well as tailor the highest
allowed security level via the @AllowExternalAccess and @AllowUnrestrictedAccess variables.
However, it was not possible to skip the creation of the Asymmetric Key and Key-based Login in
[master], even though those objects aren’t needed if the Assemblies will always be set to SAFE.
Now, those two variables have been replaced with @MaxAllowedAccessLevel that will be set to a
value of 0 to 3, where 1, 2, and 3 correspond to the same security levels used for
SQLsharp_SetSecurity, and all three levels will install the [master] Database objects. A value of 0 for
@MaxAllowedAccessLevel skip all server-level configuration, including attempting to enable CLR
Integration. This new option of 0 is intended for environments in which you have no server-level
permissions and only SAFE Assemblies are allowed. The details of what each level does are fully
documented in the installation script itself, towards the top.
The installer also does more validation now, to identify problems before installation begins.
In previous versions of SQL#, the SQLsharp_Uninstall Stored Procedure would uninstall all SQLCLR
objects from the local database, as well as the SQL# Schema, but it did not remove the SQL# User
from the local Database, nor did it remove the two objects in [master]: the Asymmetric Key and the
Key-based Login. Now SQLsharp_Uninstall does remove the SQL# User, and there is a new, pure T-
SQL Stored Procedure in [master] that drops the Key-based Login, then the Asymmetric Key, and
finally itself. SQLsharp_Uninstall even prints a reminder to the “Messages” tab that you will probably
need to execute [master].[dbo].[SQLsharp_InstanceUninstall]. This new Stored Procedure does not
run automatically at the end of SQLsharp_Uninstall as there might be other Databases with SQL#
installed that need those objects.
Another issue that one might run into is when restoring a Database that has SQL# installed onto an
Instance that has never had SQL# on it. In this scenario, code requiring security levels 2 or 3 will not
be able to execute since those elevated permissions require that Key-based Login (and that it have
the correct permission). Previously, you had to re-execute the install script to get those objects back
into [master]. But now, SQLsharp_InstanceSetup – a new, pure T-SQL Stored Procedue in the local
Database – will re-create those 3 objects in [master]. And, this new InstanceSetup Stored Procedure
is dynamically created during installation so that it can retain the value used for @SQLsharpLogin.
Previously, the SQLsharp_Help stored procedure would display all of the available commands,
including their parameter options. This worked well for a relatively well for first 100 to 150 functions,
but became much harder to maintain and less useful as SQL# continued to expand (this release – 4.0
– contains 350 objects!). So, starting with this release, the full PDF manual is included in the installer
and is imported (as a GZipped binary) into the Database along with the Assemblies. The PDF manual
will thus always be available, even if the website isn’t for any reason. You won’t have to search
around for it, and it will be included in every Database backup.
The embedded binary data includes additional meta-data along with the gzipped PDF file. The meta-
data is properties about the PDF, such as the Document Revision Number, which will make it easy to
determine if a newer version has been published, and will allow for a PDF manual update script to
prevent overwriting a newer version with an older one. There are two new functions that will get this
meta-data: a scalar function to get the Document Revision Number, and a TVF to display all of the
meta-data. And, there is a new stored procedure that will save the PDF manual to disk, provided a
path and optional filename. If no filename is specified, it defaults to the current PDF manual filename.
Please note that extracting the PDF manual requires EXTERNAL_ACCESS (Security Level 2). This
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 200 of 210
means that it will not be possible to extract if the install was done using a value of either 0 or 1 for
@MaxAllowedAccessLevel.
Highlights
RegEx cache: Similar to how queries are compiled and their execution plans get cached, Regular
Expressions – the pattern / expression itself – gets compiled (which takes time) and is then cached to
save time on subsequent executions. And, just like the plan cache, there is a limited amount of space
to use for cached expressions. The default cache size is 15 expressions. If there are more than 15
patterns / expressions that you regularly use, then the system will be spending more time than it
should recompiling the expressions that are getting forced out of the cache. This release includes two
new functions for managing the expression cache: one to set the cache to whatever size you want
(only available in the Full version) and one to display the current size of the cache (also available in
the Free version). Increasing the cache size (at least a little, not too high) so that all (or at least most)
of your expressions can fit in should make your system more efficient and your queries using
RegEx_* functions complete in less time.
There is currently no means of having a custom cache size automatically set, and so setting the
cache size will need to be done each time the App Domain is loaded. If the App Domain is unloaded
due to memory pressure, a custom cache size will reset to the default value of 15. But this is
something that could be checked periodically in a SQL Server Agent Job that also sets the value to
the desired size if it is lower than the desired size. The next release of SQL# will provide a
mechanism for setting a custom cache size each time the App Domain is created.
URI host connection limit: When accessing network resources, .NET throttles connections per each
host. The default limit for any particular host is 2. When this limit is reached, additional requests are
blocked and will wait until a process completes and frees up its connection. This means that if you
use INET_GetWebPages to hit one or more URIs that are fairly static (the host / machine portion of
the URI, that is), then you could be experiencing a lot of latency if you have a call that is made
repeatedly across multiple sessions. This release includes three new scalar functions for managing
this. There is a function to display the current connection limit for a particular host, one to display the
current connection count to a particular host, and one to set the limit for a particular host. It is unclear
what a bad upper-limit would be, but it is clear that 2 is a very low. If you have code that calls an in-
house web page or web service and is called by multiple sessions at the same time, then you need to
set the connection limit to something higher than 2, and then your process should complete faster.
There is currently no means of having a custom connection limit automatically set, and so setting a
connection limit will need to be done each time the App Domain is loaded. If the App Domain is
unloaded due to memory pressure, a custom connection limit will reset to the default value of 2. But
this is something that could be checked periodically in a SQL Server Agent Job that also sets the
value to the desired size if it is lower than the desired size. The next release of SQL# will provide a
mechanism for setting custom connection limits each time the App Domain is created.
Splitting to native types: Quite often (perhaps most often) when needing to split a string, the string
in question is a list of IDs (i.e. INT or BIGINT values). In these cases, it is much more efficient to split
directly to the numeric type as opposed to splitting to strings to then convert that string into an INT or
BIGINT value. This release includes a few new TVFs to allow for splitting into native types: two for
splitting into BIGINT (one is only available in the Full version) and one for splitting directly into
UNIQUEIDENTFIER / GUIDs (only available in the Full version). The two TVFs that are only available
in the Full version allow for determining how they handle empty elements as well as invalid elements:
exclude them, return NULL, or error. These same two TVFs also allow for tailoring whether a NULL
input value returns an empty result set (as most other TVFs do), or returns a single row of NULL.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 201 of 210
Environment Variables: This release includes several functions in the OS category (Full version
only) that can get, and in some cases set, environment variables. There are TVFs for getting a list of
all variables and their values, and UDFs to get the value of a specific variable. You can get Machine /
System variables only, User variables only, or Process variables which includes variables specific to
the process running sqlservr.exe as well as the Machine and User variables.
You can set the value of Process variables, and those values will persist beyond that call, for the life
of that process, and will even be available to a subprocess such as xp_cmdshell (unlike setting an
environment variable via xp_cmdshell which does not persist). This only requires
EXTERNAL_ACCESS (Level 2). You can also set User environment variables, and those will persist
beyond the life of the sqlservr.exe process. However, this requires UNRESTRICTED access
(Level 3) because it writes the values to the user’s registry (which is how the value persists beyond
the life of the process).
Please also note that the “User” in question is the service account running the sqlservr.exe
process (and this might not work if the process is running as “Local System”). There is no ability to
write to the Machine / Server environment variables as that presents too great of a security risk.
Performace Counters: This release includes several new functions in the OS (Full version only)
category that allow you to interact with all Performance Counters, not just the SQL Server Instance-
specific counters available via sys.dm_os_performance_counters. There is a TVF to get the full
details of a sample: RawValue, BaseValue, Frequency, TimeStamp, CounterType, etc. And there is a
UDF to get the calculated value of the most recent sample. Another UDF allows for adding a sample
value to a counter (no, the system will not allow you to add samples to system counters). Finally,
there is a function that allows for creating a new, custom Performance Counter category and counter,
but it is a very rough draft / experimental: it only allows for creating unpaired counters (i.e. not
requiring an additional “base” counter), and only allows for creating a single counter in the category. It
is possible that it will be completed in the next release (and potentially along with an
“UpdateCategory” function that allows for adding / removing counters from a category, something
which is not directly supported; it requires dropping and recreating the category).
JSON: Even though SQL Server 2016 includes native JSON support, it will be many years before
everyone is using that version (there are plenty of installations still running 2005, 2008, and 2008 R2,
as well as some still on SQL Server 2000 even). This release (Full version only) includes the first two
functions intended to help people still using a version prior to 2016. There is a UDF to convert JSON
into XML (as it can be parsed natively starting with SQL Server 2005), and one to convert XML into
JSON (as XML can be natively generated using FOR XML, also starting with SQL Server 2005).
Please keep in mind that JSON allows for anonymous arrays, a concept that does not exist in XML. In
order to handle this, the resulting XML will use “<item>” elements to represent these anonymous /
unnamed arrays.
XML: While prior versions of SQL# allowed for saving XML data to a file, that XML data first had to
be converted to NVARCHAR(MAX). That, however, does not provide a true XML document since the
XML datatype does not store either the XML declaration (i.e. the “<?xml ... ?>” node on the first line)
or any whitespace. This release includes a new function (Full version only) that can save XML data
as actual XML. Not only can you specify any encoding you want (such as UTF-8, the most common
Unicode encoding that wasn’t supported in SQL Server until 2016), but if you include the XML
declaration, you then have the option of having it include the “encoding=” property set to the name of
the encoding being used to write the file. There also options for having the output indented as well as
optionally placing each attribute on its own line (instead of the default behavior of placing all attributes
of an element on the same line).
Pagination: The need to page through a large result set, X rows at a time, is nearly universal. And,
often enough, this need also includes the requirement to get the total number of rows of the entire,
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 202 of 210
non-paged result set (in order to determine how many pages exist). One option is to use the OFFSET
and FETCH options of the ORDER BY clause. That is a good option for getting one page of the result
set, but it doesn’t get the total number of rows, and it doesn’t apply to anyone using a version prior to
2012. Another option is to dump the entire result set into a temporary table, get the total row count via
@@ROWCOUNT, and then just select the subset of rows from the temp table. But, while you don’t
need to run the query twice, that is a lot of IO writing to the temp table plus the transaction log activity.
Also, if you don’t have control over the query, but instead just have a Stored Procedure to execute,
then you can’t use OFFSET and FETCH, and instead need to dump the results to a temp table via
INSERT...EXEC. But then you need to be careful not to use the INSERT...EXEC construct within that
Stored Procedure as you will get the “INSERT EXEC statement cannot be nested” error.
This release includes a Stored Procedure (Full version only) that addresses this need. It executes any
query (including a Stored Procedure), and allows for skipping a specified number of rows while
returning a specified number of rows. It optionally allows for using an OUTPUT parameter to get the
total number of rows for the entire non-paged result set (without executing the query again!). Beyond
that, it allows for optionally including one or two extra columns at the end (i.e. far right): the row count
within the current page of results and / or the row count within the entire non-paged result set. And if
that wasn’t enough, there is also an optional parameter to override the field names of the result set.
This Stored Procedure does not load the entire result set into memory (or anywhere), so it only ever
has the current row in memory and thus should not take up any more system resources for a 10
million row result set than it does for a 10 row result set. It also will not get the “INSERT EXEC
statement cannot be nested” error, so you can execute Stored Procedures that use that construct.
Credit Card Number validation: This is one of those subjects where there is more misinformation
than correct information floating around related to how to properly determine what type of credit card
it is based on the first 6 digits (many posts and RegEx patterns only check the first 4 digits). A good
deal of research went into the improvements in this area in this release. The improvements in this
release include handling many more card types (even the new 222300-prefixed MasterCard range)
as well as a new function to simply validate the number (regardless of card type). There are two
additional functions (Full version only): one that returns the type of card (with or without validating the
number at the same time), and a TVF that, given a card number, returns the type and whether or not
it is a valid number. Please note that “valid” and “invalid” are not in any way related to “active” and
“inactive” as it is impossible to determine that active status of a card.
There will eventually be a blog post detailing the research that went into this.
Retrieve large quantities of Twitter Users: The original functions to get the various lists of Users
(i.e. Followers, Friends, Mutes, Blocks, etc) returned 20 by default and could go up to 200 when
passing in an @OptionalParameter. The problems here were: a) that not all of the SQL# Twitter
functions were able to pass in the @OptionalParameters, b) no SQL# Twitter functions supported
cursors, and c) some of the lists are tens of thousands of Users long.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 203 of 210
This release includes not only additional properties (i.e. result set columns) for both User and Status
TVFs, it also includes: a) the ability to pass in @OptionalParamaters for the remaining functions that
can support them, b) the ability to get and pass along Twitter cursor valus (so that pages of data can
be stepped through), and c) a SQL#-specific option for the “count” optional parameter whereby a
value of “all” will loop through the cursor internally so that the entire list (or as much as can be
retrieved within the rate-limit window) can be retrieved in a single execution, and returned as a single
result set. Also, new functions (Full version only) have been added to get lists of IDs to be looked up
using another new function to get a list of Users based on those IDs. The functions that get the list of
IDs are not limited to getting only 200 at a time, and can instead get thousands per each call.
String Escape Sequences: T-SQL does not have the concept of string escape sequences (e.g. \n or
\r\n = newline, \t = tab, etc) so instead we have to use CHAR(13) + CHAR(10) for \r\n, CHAR(9) for \t,
and so on, and they have to be concatenated in as opposed to the escape sequences that are done
inline. This release contains a function (Full version only) that will “un”escape all .NET string escape
sequences, including “\x” followed by 1 to 4 hex digits, “\u” followed by 4 hex digits, and others.
This functionality has been included in the handling of certain input parameters of various functions
and stored procedures where it is more common to use string escape sequences. RegEx
replacement strings as well as some of the export stored procedures in the DB category (e.g.
DB_HTMLExport) now have this ability built in.
Banker’s Rounding: Typical rounding behavior – the type of rounding that the built-in T-SQL ROUND
function does – is to round “away from zero”. Meaning, positive numbers go up (increase) and
negative numbers go down (decrease). But there is another type of rounding called “to even” that, as
the name implies, rounds to the closest even number, which might be an increase or decrease,
depending on the digit being rounded. Using this method, a value of 8.45, rounded to a single decimal
place, would result in a value of 8.4 instead of the 8.5 that would be returned from the ROUND
function. This is commonly referred to as “Banker’s Rounding” due to it being used in finances.
There are two UDFs that handle this: one using DECIMAL input and return value, and one using
FLOAT input and return value. DECIMAL is slower but more precise, and FLOAT is faster and less
precise. Ideally, financial calculations should be done using DECIMAL datatypes instead of FLOAT,
since their need to be accurate is more important than performance (end-users don’t tend to
appreciate faster calculations that are also incorrect).
There will eventually be a blog post detailing the research that went into this.
Improved LevenshteinDistance Performance: The basic algorithm for the four Levenshtein
Distance functions compares each character of one sting to each character of the other string. The
number of comparisons is the length of one string multiplied by the length of the other. Hence it is
very easy for these functions to slow down as the strings get longer. This release introduces a few
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 204 of 210
new shortcuts to reduce time spent doing unnessary comparisons: if the two strings are equal in
length then check if they are the same, if one is shorter than the other then check if it is a substring of
the longer one, etc. I will test one or two other options for improving performance for the next release.
Additionaly, all four Levenshtein Distance functions now have a @MaxDistance parameter that can
be set to a value at which to exit the calculation if that value is reached, rather than proceeding to get
the actual distance. The SQL# implementation of the Levenshtein and Damerau-Levenshtein
distance algorithms is now one of the very few that truly short-circuit (i.e. exit early) rather than merely
reducing how much of the strings to compare.
There will eventually be a blog post detailing the research that went into this.
Improved Code Page and Unicode Support: In prior versions of SQL#, functions that allowed for
specifying a file’s encoding only allowed for specifying the six named .NET encodings: ASCII,
UNICODE [implied Little Endian], UTF7, UTF8, UnicodeBigEndian, and UTF32 [implied Little Endian].
As of this release, aliases have been added to make your code easier to read for those who are not
aware of Microsoft using “Unicode” to mean UTF-16 Little Endian, as well as the new ability to specify
UTF-32 Big Endian.
Additionally, there are several new encoding names that allow for saving files without a Byte Order
Mark (BOM) for the few encodings that have BOMs. By default, the named .NET encodings include
the BOM when saving files, but there are times when this behavior is undesirable.
AND, it is now possible to pass in a number instead of an encoding name. Any value that can be
converted to an Int will be interpreted as a Code Page.
New Functionality
Category Free Version Additional in Full Version
DB WaitForDelay
File GetHashBinary (suggested by Kevin Greiner),
GetCRC32, GetFullPath (suggested by Jason
Pierce)
Math CompoundAmortizationSchedule2,
RoundToEvenDecimal,
RoundToEvenFloat
Util IsValidCCNumber GetCreditCardInfo, GetCreditCardType, Paginate
OS ServiceAccount GetEnvironmentVariable, GetEnvironmentVariables,
GetMachineEnvironmentVariable,
GetMachineEnvironmentVariables,
GetUserEnvironmentVariable,
GetUserEnvironmentVariables,
IsBinarySidAValidWindowsAccount,
IsSddlSidAValidWindowsAccount,
PerfCounterAddData, PerfCounterCreateCategory,
PerfCounterGetSample, PerfCounterGetValue,
SetEnvironmentVariable,
SetUserEnvironmentVariable,
TranslateSddlSidToName
String SplitInts (and 4k), ToLowerInvariant (and CompareWithDynamicCollation, SplitIntoGuids (and
4k), ToTitleCase (and 4k), 4k), SplitIntoIntegers (and 4k) ,
ToUpperInvariant (and 4k), SplitKeyValuePairs4k, Unescape (and 4k)
TryParseToDateTime,
TryParseToDecimal (suggested by
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 205 of 210
Jason Pierce)
Twitter Twitter_GetUserByScreenName GetApiResponseJSON, GetApiResponseXML,
GetBlockedUserIDs, GetFollowerUserIDs,
GetFriendUserIDs, GetMutedUserIDs,
GetStatusesByStatusIDs,
GetUsersByScreenNames, GetUsersByUserIDs,
UnRetweet
Sys AllAssemblies, AssemblyName
RegEx CaptureGroupCapture (and 4k), CaptureGroupCaptures, SetCacheSize
GetCacheSize, Index, MatchLength4k
Convert BinarySidToSddl, SddlSidToBinary
INET GetConnectionLimitForURI,
GetCurrentConnectionCountForURI,
SetConnectionLimitForURI
JSON JSONtoXML, XMLtoJSON
XML SaveToFile
Date FormatOffset (suggested by Jason
Pierce)
SQLsharp InstanceSetup, ManualMetadata,
ManualRevisionNumber,
SaveManualToDisk, UnloadAppDomain
Misc. master.dbo.SQLsharp_InstanceUninstall
Improved
GENERAL:
o Reviewed and cleaned up a lot of the early code / technical debt.
o Streamlined build process.
o Most functions requiring elevated permissions now display an error message containing the exact
statement to execute to fix the problem. The remaining functionality missing this detailed error
message will be addressed in the next release.
o Reduced size of main SQL# assembly by 47 KB, while at the same time adding functionality.
o REMOVED DB_XOR as it was unnecessary. Instead use built-in " ^ (Bitwise Exclusive OR)"
operator.
o The @FileEncoding parameter of any Function or Stored Procedure now accepts all encodings
found here ( https://msdn.microsoft.com/en-us/library/system.text.encoding.aspx#Anchor_5 ).
Values can be from the "Code Page" column or the "Name" column. Additionally, you can use the
following values, some being SQL#-specific (use one of the “NoBOM” values if you are writing to
a file and need to omit the Byte Order Mark / BOM):
ASCII
UTF7
UTF8 / UTF8NoBOM
UTF16 / UTF16Le / Unicode
UTF16NoBOM / UTF16LeNoBOM / UnicodeNoBOM
UTF16Be / BigEndianUnicode
UTF16BeNoBOM / BigEndianUnicodeNoBOM
UTF32 / UTF32Le
UTF32NoBOM / UTF32LeNoBOM
UTF32Be, UTF32BeNoBOM
Installation Script:
o Removed “GO” after “USE” statement so that any error with “USE” (which will be a parse error)
will fail the entire script. Previously (with the “GO” statement) if there was an error with the “USE”
statement, that batch would fail, but the script would proceed to install SQL# into whatever
database was current / active.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 206 of 210
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 207 of 210
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 208 of 210
Fixed
File_GetFile:
o (BREAKING CHANGE) It would only properly handle files encoded as the system default or
one of the Unicode encodings (as long as it included the Byte Order Mark / BOM). Added
@FileEncoding input parameter to force the encoding when no BOM is present. Leaving
@FileEncoding set to NULL will cause it to behave as it previously did (i.e. will auto-detect IF
a BOM is present, else will assume system default, which is most likely non-Unicode, 8-bit
Extended ASCII).
File_ChangeEncoding:
o (BREAKING CHANGE) Did not always translate correctly as source encoding was being
auto-detected but not all encodings use Byte Order Marks, and the ones that do use them do
not require that they be used. Added @CurrentEncoding to explicitly set the encoding of the
source file.
o No longer errors if @FilePathNew is NULL.
File_CopyMultiple, File_DeleteMultiple, File_GetDirectoryListing, and File_MoveMultiple:
o Properly handles C:\ (doesn’t require “C:\\\”) and \\Server\Share (doesn’t require
“\\\\Server\Share”).
File_CurrentEncoding:
o Correctly reports encodings.
String_LevenshteinDistance, String_LevenshteinDistancePlus,
String_DamerauLevenshteinDistance, and String_DamerauLevenshteinDistancePlus:
o Now handle spaces properly when using 'IgnoreSymbols' @ComparisonOption.
Util_GenerateIntRange, Util_GenerateDateTimeRange, and Util_GenerateFloatRange:
o Now include the upper-end value.
RegEx_Split:
o Fixed minor bug related to @StartAt parameter
o Fixed minor bug related to @Count parameter
Twitter (all functions returning a string value or field):
o Fixed handling of Supplementary Characters (often used for Emoji).
DB_BulkExport:
o ColumnHeaderHandling of "always" did not work. No rows returned would not print column
headers.
DB_ForEach:
o Schema name for each Table was not always correct.
DB_BulkCopy:
o Default destination changed: was "(local)", now correctly detects current instance, whether it
is a default instance (will use "(local)"), a named instance (will use
"ServerName\InstanceName"), or SQL Server Express LocalDB (will use
"np:\\.\pipe\LOCALDB#xxxxxxxx\tsql\query");
o (Behavior Change) Default database was "tempdb" and is now unspecified, hence it will use
the Login's default DB (so as to not increase contention on "tempdb").
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC
Page 210 of 210
SQLsharp_GrantPermissions:
o Now grants EXECUTE on User-Defined Aggregates (Agg_*) and User-Defined Types
(Type_*).
o User and Role names -- passed into @GrantTo -- with embedded single-quotes are now
handled properly (but who would ever do that, right?)
Math_Truncate:
o Now handles negative numbers correctly (was rounding down).
INET_GetWebPages:
o Properly handles standard HTTP headers (specifically: Content-Type, Referer, User-Agent,
Connection, Transfer-encoding, and Range)
o Properly handles PUT method:
Sends @PostData.
If @PostData is NULL or empty string, will send Content-Length header as 0.
INET_HTMLEncode:
o Encodes apostrophes as "'" instead of "'".
o Now encodes spaces (as " ") instead of ignoring them.
INET_HTMLDecode:
o Decodes " " (as a space) instead of ignoring them.
o Decodes "'" (as an apostrophe) instead of ignoring them.
SQL#
Version 4.0.95 / 4.0.96 (doc. rev. 20170325)
Copyright © 2006 – 2017 Sql Quantum Lift, LLC