Author: way0utwest

  • The Development Backup

    Have you ever had a development server crash? Have you lost work because of this? Had delays or had to recreate code? You shouldn’t, or at least you shouldn’t lose much work or time..

    There was a time when I offered to manage backups on all development servers. This was in a large environment with hundreds of instances.  I wasn’t worried. I had scripts to do the work of setting up, running, and reporting on backups for instances. I knew how to deploy these scripts to hundreds of servers.

    My reasoning was the our development servers were really our manufacturing environment for software. Wouldn’t you ensure your machinery was well maintained and kept in top condition if you had a factory? I know I would.

    The developers passed and once in awhile they’d call and ask of we could recover a server. 

    “Do you have backups?,” I’d ask. “No” was the usual reply. I’d appligize and reiterate my offer to manage the system. They were always resistent and that was fine. They were responsible, and these were their systems. However they had a backup system already. They just didn’t use it.

    Almost all of these people were using a version control system (VCS) for their code, but not for database code. Do me a favor; put your database object code in source control. Add all your DDL for tables, views, functions, stored procedures, and anything else you use.

    As long as it’s on a different physical machine than the development server, you’ll thank me one day.

    Just as long as you also run backups of that VCS database.

    Steve Jones

    The Voice of the DBA Podcast

    Listen to the MP3 Audio ( 1.7MB) podcast or subscribe to the feed at iTunes and LibSyn. feed

    The Voice of the DBA podcast features music by Everyday Jones. No relation, but I stumbled on to them and really like the music. Support this great duo at www.everydayjones.com.

     

  • The MCM Saga

    There was a comment posted on my Connect item for Open Sourcing the MCM. It said:

    “I have been able to contact the MS Learning team and they have given me some information about the content. My restatement of that, is that the ownership of the content is a bit complex. Some content is owned by other groups at Microsoft and is being repurposed for delivery in other workshops. In some cases the content is canibalized into a substantially different form. In some cases content was paid for and licensed content for a specific use, and it can’t just be reissued. At any rate, Microsoft doesn’t want to waste the money spent on it, and efforts are being made to use it in some manner. But you won’t see a consistent publishing pattern.”

    That’s reasonable, and I’m sure it’s true. I know multiple people worked on the project, and perhaps there is IP from some people that they don’t want released. I understand that, though I don’t like it.

    I made my case for this, and while plenty of MCMs disagreed, I was looking at this as a way to improve the community’s knowledge in building applications. Having specific scenarios to work through could help administrators and developers understand what types of real world problems they may face, or even introduce in their designs.

    It’s easy to say there’s all this information out there, but it’s incredibly unorganized. I’ve started to try and organize my content, build shorter, smaller posts that lead through a solution. I’m trying to help people (and myself) grow knowledge in a targeted way. Too much of the stuff out there doesn’t do that.

  • FileTable– Using GetParent for Inserts

    In a previous post, I looked at the ways in which I could insert files into a Filetable folder programmatically. I used a NEWID() generation process, which mimics the constraint that is coded in the Filetable schema. However there was a comment asking if I could, or rather would, use the HierarchyID methods. It was on my list to investigate, so here it is.

    I have a file, actually an image, that looks like this:

    circle

    It’s a circle image, and the insert statement actually looks like this:

    INSERT  INTO dbo.Pictures
            ( name
            , file_stream
            )
    VALUES  ( 'circle.jpg'
            , 0xFFD8FFE000104A46494600010101006000600000FFE100684578696600004D4D002A000000080004011A0005000000010000003E011B0005000000010000004601280003000000010002000001310002000000120000004E00000000000000600000000100000060000000015061696E742E4E45542076332E352E313000FFDB0043000201010201010202020202020202030503030303030604040305070607070706070708090B0908080A0807070A0D0A0A0B0C0C0C0C07090E0F0D0C0E0B0C0C0CFFDB004301020202030303060303060C0807080C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC0001108000A000D03012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00E97FE0E87FF82CA7ED35FB04FED85E09F03FC2BD6A5F87BE1097408B5C4D523D2ADAF1BC41746795248CBDC4722F970848C18940399373E43478FD75FF00827CFC68F177ED17FB0FFC2AF1D78F3461A078C7C59E19B2D4F57B110B42B14F244199846DF346AFC384392A1C024E335E95E2EF87BE1FF880968BAF687A3EB6B612F9F6C2FECA3B916F27F7D3783B5BDC60D6C5007FFFD9
            );

    That puts the file in my Filetable in the root. However suppose I actually wanted that in a folder. Here’s my Filetable share and you’ll note I have a folder called Shapes.

    filetable_zb

    Can I insert this file directly in there, using T-SQL? Let’s try.

    I wrote some code that would get the parent path and use that with GetDescendent(). However that didn’t work. I ran this:

    DECLARE @parent HIERARCHYID, @node HIERARCHYID
    SELECT @parent = path_locator 
     FROM dbo.Pictures
     WHERE name = 'Shapes';
    
    SELECT @node = max(path_locator)
     FROM dbo.Pictures
     WHERE path_locator.GetAncestor(1) = @parent
    
    SELECT @parent, @node;
    
    
    INSERT  INTO dbo.Pictures
            ( name
            , file_stream
            , path_locator
            )
    VALUES  ( 'circle.jpg'
            , 0xFFD8FFE000104A46494600010101006000600000FFE100684578696600004D4D002A000000080004011A0005000000010000003E011B0005000000010000004601280003000000010002000001310002000000120000004E00000000000000600000000100000060000000015061696E742E4E45542076332E352E313000FFDB0043000201010201010202020202020202030503030303030604040305070607070706070708090B0908080A0807070A0D0A0A0B0C0C0C0C07090E0F0D0C0E0B0C0C0CFFDB004301020202030303060303060C0807080C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC0001108000A000D03012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00E97FE0E87FF82CA7ED35FB04FED85E09F03FC2BD6A5F87BE1097408B5C4D523D2ADAF1BC41746795248CBDC4722F970848C18940399373E43478FD75FF00827CFC68F177ED17FB0FFC2AF1D78F3461A078C7C59E19B2D4F57B110B42B14F244199846DF346AFC384392A1C024E335E95E2EF87BE1FF880968BAF687A3EB6B612F9F6C2FECA3B916F27F7D3783B5BDC60D6C5007FFFD9
            , @parent.GetDescendent(@node,NULL)
            );

    and got this:

    Msg 6506, Level 16, State 10, Line 20

    Could not find method ‘GetDescendent’ for type ‘Microsoft.SqlServer.Types.SqlHierarchyId’ in assembly ‘Microsoft.SqlServer.Types’

    I found a note on StackOverflow that the implementation of the hierarchyID in a Filetable isn’t the same as elsewhere. I’m not sure if that’s the case, but I haven’t been able to document it.

    However I decided to then try the method proposed as a comment in my last post. Insert, and then move.

    DECLARE @id TABLE ( id UNIQUEIDENTIFIER )
    DECLARE @streamid UNIQUEIDENTIFIER
      , @parentpath HIERARCHYID
      , @folder VARCHAR(1000);
    
    SELECT  @folder = 'Shapes';
    
    INSERT  INTO dbo.Pictures
            ( name
            , file_stream
            )
    OUTPUT  inserted.stream_id
            INTO @id
    VALUES  ( 'circle.jpg'
            , 0xFFD8FFE000104A46494600010101006000600000FFE100684578696600004D4D002A000000080004011A0005000000010000003E011B0005000000010000004601280003000000010002000001310002000000120000004E00000000000000600000000100000060000000015061696E742E4E45542076332E352E313000FFDB0043000201010201010202020202020202030503030303030604040305070607070706070708090B0908080A0807070A0D0A0A0B0C0C0C0C07090E0F0D0C0E0B0C0C0CFFDB004301020202030303060303060C0807080C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC0001108000A000D03012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00E97FE0E87FF82CA7ED35FB04FED85E09F03FC2BD6A5F87BE1097408B5C4D523D2ADAF1BC41746795248CBDC4722F970848C18940399373E43478FD75FF00827CFC68F177ED17FB0FFC2AF1D78F3461A078C7C59E19B2D4F57B110B42B14F244199846DF346AFC384392A1C024E335E95E2EF87BE1FF880968BAF687A3EB6B612F9F6C2FECA3B916F27F7D3783B5BDC60D6C5007FFFD9
            );
    
    SELECT  @streamID = id
    FROM    @id
    SELECT  @parentpath = path_locator
    FROM    dbo.Pictures
    WHERE   name = @folder
    
    UPDATE  dbo.Pictures
    SET     path_locator = path_locator.GetReparentedValue(hierarchyid::GetRoot(),
                                                           @ParentPath)
    WHERE   stream_id = @StreamId

     

    In this code, I insert the file, but save the PK, the streamID using the OUTPUT clause. From there, I get the path of the folder, and then I use the GetReparentedValue function to move the file to the folder.

    That works fine, and I look in my folder after running this and see the file.

    filetable_zc

    I’m not sure what the difference with the hierarchyIDs is with a Filetable, or why operations on Filetable structures cause errors with some functions, but this seems to work and is likely a better way to handle any of your T-SQL manipulations with Filetable data.

  • What are you worth?

    Each of us is reponsible for negotiating his or her own salary for a position. Often we don’t have much leverage to exact a higher salary, and even if it’s deserved, so many companies don’t have the flexibility for managers to pay higher salaries than what is set in some range by their HR group. That’s discussed a bit in this post from Chris Shaw that looks at hiring and salaries.

    I’ve always felt that the way we handle salary was developed by owners and managers, and the process benefits them, not the employees. We rarely discuss salaries at work, with disclosure sometimes forbidden. Your salary adjustments over time seem to be highly based on your current salary. That means that your starting salary often determines your future salaries at a company, regardless of your abilities relative to others or the market. Even changes in supply and demand may not affect your salary.

    A few companies have set salary ranges publicly within the company and some even disclose salaries among employees. It sounds strange to many of us, but I’ve talked with a few people that work in those environments and it’s not a big deal. You earn your salary or you don’t, and if you do a good job, no one complains. If you don’t do a good job, then many of these companies are quicker than most to ask you to take a pay cut or leave. Personally, I like that type of environment.

    I doubt we’ll have open disclosure going forward, but fortunately many of us have the ability to change employers easily with our skills if the markets change and we feel we’re underpaid. The flip side is that there can be competition for your job and companies might find it easier to let you go and choose someone else that provides the company a better value.

    The only advice I would give most people looking to negotiate salary these days is that you should ask for what you’re worth, even if it seems high to you. The worst thing that usually happens is the employer says no and offers you a lesser amount. However, if you don’t ask, you won’t get the salary you want.

    Steve Jones

    The Voice of the DBA Podcast

    Listen to the MP3 Audio ( 2.4MB) podcast or subscribe to the feed at iTunes and LibSyn. feed

    The Voice of the DBA podcast features music by Everyday Jones. No relation, but I stumbled on to them and really like the music. Support this great duo at www.everydayjones.com.