Giter VIP home page Giter VIP logo

mysqlclrfunctions's Introduction

MySQLCLRFunctions

Free SQLCLR functions tested on SQL Server 2019

These are simple functions I've written in order to avoid spending $500 for a two year license (https://sqlsharp.com/full/) of SQL#. For one, the product hasn't been updated in 2 years, and that's not very cool for a pay product.

FYI, warning, buyer beware on my stuff: I use UNSAFE assemblies, because half the reason to use SQLCLR is to get to functions that are not in SQL Server already, which is where the safe stuff is.

Another bug I have with SQL# is that their names are overly precious. They will name a function SQL#.string_Is_BEGINNING_WITH whereas I call it StartsWith, which is not coincidentally the same as the C# method. I try to align my names with C# when the functionality aligns. Less to remember.

I also have less arguments on functions than SQL#. SQL Server does not support optional arguments on functions, and so these are annoying to have to fill out. Also, I forget what they are supposed to be, and I don't recall their documentation telling me if using DEFAULT will work. Rather than every possible argument under the sun, I do it the old fashion way: I make a new function. For example, hypothetically, I would do this:

  • CompareThese(a,b)
  • BestOf3(a,b,3)
  • BestOf4(a,b,c,d)
  • Or make an agg or a TVF.
  • For reduced maintenance, I pass everything as NVARCHAR(MAX) as well as return NVARCHAR(MAX). Speed is not my main problem. The main problem is that SQL Server functions are severely lacking and new functions are added every third decade. STRING_AGG is great, but a SQLCLR function can go back to at least 2012.

    I do suspect that there may be memory allocation issues with this design, and so I may come up with a generative way to make VARCHAR(8000) or NVARCHAR(4000) clones. Due to the way SQL Server pre-allocates memory, it may be even better to support smaller sizes. Not really sure.

    If it's possible to think of a logical algorithm that can easily be described and understood, and there's no confusion about what to expect in the output, then it's worth being a function.

    For instance, I have a function called AnyOneOfTheseIsInThose, or something like that. It is for when I to know if there is a non-empty intersection of a list of values that I don't want to stuff into tables. It answers the simple question: Are any of these items in this other list?

    To pass in lists, I use delimited strings, but I usually have an argument for the separating string. SPLIT_STRING from Microsoft, and most home-grown SQLCLR splitters seem to think all splitting is based on single characters. I support the string for the cases that come up.

    Structure or class organization, namespaces in other words:

  • Adaptors - Converts something to something else as an electronic power adaptor would. It's not a transformation, and it's reversible.
  • Compares - Comparisons. Since generics aren't supported, The name includes the type (like olden days). Often in SQL I need to get the greatest between two or a few things. Greatest between PURCHASE_DATE and QUOTE or some such. Usually between two or more events that could happen in either order.
  • Environmental - I'm Windows centric. Sorry. So I try to "beep" sometimes in code, and I'm pretty sure the SQLCLR context is boxed out of beeping, so it doesn't work. But it will, someday. I want things like "You're data is ready, Captain." Might help the alertness quotient.
  • FileNameExtract - Dumb name. But using .NET FileInfo is a major load for processing say millions of documents off a shared drive. I should be able to replace FileInfo with some straight-forward parsing.
  • Humanization - One of the most common functions around, but never really fully cooked, is it. So this is yet-another attempt, and I may look around out there for better ones to borrow. DBAs/Developers never pause to think: Who is my audience? Do they need to see rows and rows with 30 date-time columns? If they're all sub-second from now, then say so. We need a "yada yada yada" function. If one sticks out and says "Last year", it should stick out! If there's a 9198, maybe it's really 1998? I've had SQL Server blow on DATETIME with an Oracle DATE value of 0200, a typo which Oracle tolerates in a DATE column, but SQL Server did not. DATE and DATETIME2 are better.
  • NetworkCollect - Not sure what I was thinking. Collect?
  • NetworkTest - I use the "Test" suffix a lot. "Ping" is important, but SQL Server feels like that's a job for System Engineers. Well, if I'm scanning my SQL Servers or a list of possible Servers, then if I try to connect to each one, there will be a lot of time outs, and the default time out is about 30 seconds, or 20. I turn that down, but if the host doesn't exist at all in Active Directory, then the timeout is defined by the OS, and SQL Server goes blithely on with waiting.
  • StringExtract - This is a bit Polish-Hungarian for sorting. These are all the functions that extract something from a string or a string of substrings. Here's an example of constant use in C#, which is not really something you get in SSMS or SQLCMD. It's nice! I add functions that seem like an oversight. "LeftOf" some charactor or string. Why do I have to do CASE WHEN CHARINDEX(',', s) > 0 THEN SUBSTRING(s, CHARINDEX(',', s)-1 ELSE NULL END??????

    ARGH!

  • StringMeasure - Separate from extraction, we are instead taking measure of something, so new information is being gained, even though it is deductive information. Extracts are to avoid providing new information, but rather only provide a substring that exists within the source.
    HowMany. Simple enough! How many commas? We are pulling in a CSV, and missing commas or extras will break it.
  • StringTest - Returns 1 or 0! Very bitty. These are probably deterministic. I hope. A lot of "Is it" and "Does it" questions.
  • StringTransform - Actual change being made, new information by structural abruption.

  • My favorites have to be Matches, Ping, StartsWith, EndsWith, AnyOfTheseeAreAnyOfThose, HowMany, LeftOf, LeftOfNth, LeftOfNth, IndexOfLast Also GetFirstName, Pieces, RTrimChar.

    I have a bunch somewhere, and I need to add more.

    Some ideas:

    - Better captures of stored procedure output or xp_cmdshell return strings. - Escape function for multi-level dynamic SQL generation. - A UNIX cut command for fixed-width. - CSV, XML, Excel in/out. - HTML table generation for emails. - Intelligent Substring Title casing, like "ROTC" is not "Rotc". - Smarter name normalization, accent removals for us Americanos. - SQL formating more to my tastes. - Some default formatters, like LogFileTimeStamp = "YYYYmmDDhh24missffffff" or some such. So I don't have to remember. - Pivot code I found for true column-to-row pivot. - Possibly push SQL work down? Like a TRUNCATE TABLE that pre-strips FKs, truncates, reloads, and tries to add the FKs back. - Unix to/from for Active Directory columns. - Natural language extraction of patterned speech.

    mysqlclrfunctions's People

    Contributors

    jeffshumphreys avatar

    Stargazers

     avatar  avatar  avatar  avatar  avatar  avatar  avatar

    Watchers

     avatar  avatar

    Forkers

    stromejl

    mysqlclrfunctions's Issues

    Pull in https://github.com/Humanizr/Humanizer rather than bother writing anymore

    https://github.com/Humanizr/Humanizer

    Massive functionality, and MIT as well.

    "Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities. It is part of the .NET Foundation, and operates under their code of conduct. It is licensed under the MIT (an OSI approved license)."

    ByteSize.Parse("1.55 gB");
    var b = (10.505).Kilobytes();
    (1024).Gigabytes().ToString(); // 1 TB
    maxFileSize.LargestWholeNumberSymbol; // "KB"
    b.Humanize("#.## B"); // 10757.12 B
    (1000).Kilobytes().ToFullWords(); // 1000 kilobytes
    (4.7).Terabytes();
    3.Bits();
    var fileSize = (10).Kilobytes();
    1.ToRoman() => "I"
    new DateTime(2015, 1, 1).ToOrdinalWords() => "January 1st, 2015"
    new DateTime(2015, 2, 12).ToOrdinalWords() => "February 12th, 2015"
    new DateTime(2015, 3, 22).ToOrdinalWords() => "March 22nd, 2015"
    10.ToOrdinalWords(new CultureInfo("en-US")) => "tenth"
    5.Ordinalize() => "5th"
    121.ToOrdinalWords() => "hundred and twenty first"
    3501.ToWords() => "three thousand five hundred and one"
    3.Hundreds().Thousands() => 300000
    1.25.Billions() => 1250000000
    3.Hundreds().Thousands() => 300000
    someDateTime.At(2, 20, 15)
    On.November.The13th.In(2010).AtNoon + 5.Minutes()
    In.One.Second // DateTime.UtcNow.AddSeconds(1);
    In.TheYear(2010) // Returns the first of January of 2010
    In.FebruaryOf(2009) // Returns 1st of February of 2009
    In.Two.SecondsFrom(DateTime dateTime)
    DateTime.Now + 2.Days() + 3.Hours() - 5.Minutes()
    2.Hours() => TimeSpan.FromHours(2)
    "SomeTitle".Underscore() => "some_title"
    "some_title for something".Camelize() => "someTitleForSomething"
    "case".ToQuantity(5, ShowQuantityAs.Words) => "five cases"
    "case".ToQuantity(5, ShowQuantityAs.None) => "cases"
    "man".ToQuantity(1) => "1 man"
    "man".ToQuantity(2) => "2 men"
    Vocabularies.Default.AddSingular("(vert|ind)ices$", "$1ex");
    Vocabularies.Default.AddIrregular("person", "people");
    Vocabularies.Default.AddUncountable("fish");
    Vocabularies.Default.AddPlural("bus", "buses");
    collection.Humanize() // "Specific String, Specific String, and Specific String"
    collection.Humanize(sc => sc.SomeInt.Ordinalize(), "or") // "1st, 2nd, or 3rd"
    TimeSpan.FromMilliseconds(1299630020).Humanize(3, toWords: true) => "two weeks, one day, one hour"
    DateTime.UtcNow.AddHours(-30).Humanize() => "yesterday"
    DateTime.UtcNow.AddHours(-2).Humanize() => "2 hours ago"
    DateTime.UtcNow.AddHours(30).Humanize() => "tomorrow"
    DateTime.UtcNow.AddHours(2).Humanize() => "2 hours from now"
    DateTimeOffset.UtcNow.AddHours(1).Humanize() => "an hour from now"
    "To be formatted -> {0}/{1}.".FormatWith(1, "A") => "To be formatted -> 1/A."
    "Long text to truncate".Truncate(2, Truncator.FixedNumberOfWords) => "Long text…"
    "Sentence casing".Transform(To.LowerCase) => "sentence casing"
    "Sentence casing".Transform(To.SentenceCase) => "Sentence casing"
    "Sentence casing".Transform(To.TitleCase) => "Sentence Casing"
    "Sentence casing".Transform(To.UpperCase) => "SENTENCE CASING"
    "Pascal case input string is turned into sentence".Dehumanize() => "PascalCaseInputStringIsTurnedIntoSentence"
    "Underscored_input_String_is_turned_INTO_sentence".Humanize() => "Underscored input String is turned INTO sentence"

    It's not framework, so I'll have to cut and paste.

    Table-Valued methods invalidly specified

    I blame the example I copied - all the more reason to make gooder examples.

    I was missing the SqlFunction attribute TableDefinition. I fixed one, but I need to fix all of them.

    Complete UnitTesting MSTest v2

    Just a matter of walking through and creating at least one test.
    Then flushing out negative tests, space tests, large string tests, empty string tests, nulls, negative 1s.

    NVARCHAR(MAX) is probably a bad idea

    Not a bug per se, but if it keeps blowing memory because of it, then it's a bug.

    Try SqlChar and alternate named functions like "Left{100}C" Ugh!!!!! bizarro function names!

    Not SubString4K for heaven's sake.

    And I want a variant whereby VARCHAR(100) is used. Maybe even the default, which is another breaking change, but is NVARCHAR really the standard? Over double the space for ASCII?
    Now "FirstName" is NVARCHAR of course. That is also another reason to have hyper-specific naming.

    No one gives a fuck (flying)

    I write and I write. Fortunately I love and use this code, and I'm finally of the age where I'm willing to care long-term about something. So no one cares - who would? Am I special? Is my code? Am I looking to work with other people's dumb ideas? No.

    Generated SQL Push file

    Right now SQLCLR_Register.sql is manually maintained, which was necessary to learn all the variations. But this can be generated from a scan of the functions in the code with a [SqlFunction] attribute. Not sure how to do, though.

    Get XML/JSON dll to work in SQLCLR

    https://nielsberglund.com/2017/07/23/sql-server-2017-sqlclr---whitelisting-assemblies/

    https://nielsberglund.com/2017/07/02/sql-server-2017-sqlclr-and-permissions/

    "Microsoft introduced an sp_configure option called clr strict security, which by default is set to 1 (on). When the setting is on, SQL Server treats all assemblies (SAFE, EXTERNAL_ACCESS, UNSAFE) as if they were marked UNSAFE."

    sp_add_trusted_assembly
    [ @hash = ] 'value'
    [ , [ @description = ] 'description' ]

    "The slightly interesting thing with this is that even when you mark an assembly as trusted, it still has to be created with the correct permission set."

    "The security choices you now have for an assembly in SQL Server 2017 are:

    The database is set to be TRUSTWORTHY, OR
    The assembly is signed with a certificate that has a corresponding login with UNSAFE ASSEMBLY permission, OR
    The assembly is signed with an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission, OR
    The assembly is marked as trustworthy by the sys.sp_add_trusted_assembly procedure."

    https://nielsberglund.com/2017/07/01/sqlclr-and-certificates/

    Environmental class doesn't make any sound

    Describe the bug
    They don't raise an error, but they make no sound. Console.Beep may be blocked somehow, especially under "runas"

    Probably will switch to playing files.

    Complete UnitTesting xUnit

    Maybe not the sweetheart, but over MSTest it 1) supports Regexp. Also methods are shorter, so NotNull instead of IsNotNull. Not sure what the means, but without Regexp I cannot survive in this life.

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. 📊📈🎉

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google ❤️ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.