{"id":59,"date":"2011-05-16T17:24:00","date_gmt":"2011-05-16T15:24:00","guid":{"rendered":"https:\/\/daniel.liljeberg.io\/?p=59"},"modified":"2021-01-01T20:12:13","modified_gmt":"2021-01-01T19:12:13","slug":"sql-in-without-dynamic-sql","status":"publish","type":"post","link":"https:\/\/daniel.liljeberg.io\/sv\/2011\/05\/16\/sql-in-without-dynamic-sql\/","title":{"rendered":"SQL IN() without dynamic SQL"},"content":{"rendered":"<p class=\"wp-block-paragraph\">Got a question a while ago how to solve a problem that involved a SQL stored procedure containing the use of \u2018IN\u2019 whose data you submitted to the procedure. This was solved as many solve it, with dynamic SQL. This can be likened to building your SQL query from strings in your SP and then executing the query. For example<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CREATE PROC foobar @ids as nvarchar(500) as\nbegin\n  declare @sql as varchar(500)\n  SET @sql='select foo from bar where foo_id in ('+@ids+')'\n \n  ...\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u2018ids\u2019 here is a comma-separated list of the id&#8217;s that we want to do our look up against. The dynamic SQL query is not part of our SP but runs in its own scope. The disadvantage of this approach, however, is that it is not so easy for the query optimizer to be able to figure out how to best run your query. In addition to this, users of our SP must now also have SELECT rights on all tables from which we in our dynamic query retrieve data. You do not need this for an SP as the rights are set to the SP and it then does not matter which tables our SP retrieves data from. Dynamically generating your query can also leave the door open for SQL injections. If you find yourself in a situation where you need to use dynamic SQL, try always executing them with \u2018sp_executesql\u2019.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One way to keep the ability to dynamically send data to \u2018IN\u2019 but avoid dynamic SQL is to create a function that splits your comma separated list and saves the values \u200b\u200bin a temporary table which you then use for your look up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A function for splitting a string can be done in many ways. Below is a variant that makes it possible to choose which character you want to split.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CREATE FUNCTION dbo.Split(@String varchar(8000),\n                          @Delimiter char(1))\nreturns @temptable TABLE (items varchar(8000))\nas\nbegin\ndeclare @idx int\ndeclare @slice varchar(8000)\n \n    select @idx = 1\n    if len(@String)&lt;1 or @String is null return\n \n    while @idx!= 0\n        begin 14 set @idx = charindex(@Delimiter,@String)\n        \n        if @idx!=0 16 set @slice = left(@String,@idx - 1)\n        else 18 set @slice = @String 19 20 if(len(@slice)>0)\n        \n        insert into @temptable(Items) values(@slice)\n        \n        set @String = right(@String,len(@String) - @idx)\n        \n        if len(@String) = 0 break\n        \n    end\n    return\nend<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now you can use this feature and split your string containing your id&#8217;s.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CREATE PROC foobar @ids as nvarchar(500) as\nbegin\n    declare @sql as varchar(500)\n    \n    SELECT foo FROM bar WHERE foo_id IN(SELECT CONVERT(int, items) FROM dbo.Split(@ids, ','))\n    \n...\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, dynamic SQL is not always bad and can sometimes be just the way to go. So test both solutions and see what works best for your particular purpose. But keep an eye on the security details.<\/p>","protected":false},"excerpt":{"rendered":"<p>Got a question a while ago how to solve a problem that involved a SQL stored procedure containing the use of \u2018IN\u2019 whose data you submitted to the procedure. This was solved as many solve it, with dynamic SQL. This can be likened to building your SQL query from strings in your SP and then&hellip;&nbsp;<a href=\"https:\/\/daniel.liljeberg.io\/sv\/2011\/05\/16\/sql-in-without-dynamic-sql\/\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">SQL IN() without dynamic SQL<\/span><\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","neve_meta_reading_time":"","footnotes":""},"categories":[7],"tags":[],"class_list":["post-59","post","type-post","status-publish","format-standard","hentry","category-sql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>SQL IN() without dynamic SQL - Daniel Liljeberg<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/daniel.liljeberg.io\/sv\/2011\/05\/16\/sql-in-without-dynamic-sql\/\" \/>\n<meta property=\"og:locale\" content=\"sv_SE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SQL IN() without dynamic SQL - Daniel Liljeberg\" \/>\n<meta property=\"og:description\" content=\"Got a question a while ago how to solve a problem that involved a SQL stored procedure containing the use of \u2018IN\u2019 whose data you submitted to the procedure. This was solved as many solve it, with dynamic SQL. This can be likened to building your SQL query from strings in your SP and then&hellip;&nbsp;Read More &raquo;SQL IN() without dynamic SQL\" \/>\n<meta property=\"og:url\" content=\"https:\/\/daniel.liljeberg.io\/sv\/2011\/05\/16\/sql-in-without-dynamic-sql\/\" \/>\n<meta property=\"og:site_name\" content=\"Daniel Liljeberg\" \/>\n<meta property=\"article:published_time\" content=\"2011-05-16T15:24:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-01-01T19:12:13+00:00\" \/>\n<meta name=\"author\" content=\"Daniel Liljeberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Skriven av\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daniel Liljeberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Ber\u00e4knad l\u00e4stid\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minuter\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2011\\\/05\\\/16\\\/sql-in-without-dynamic-sql\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2011\\\/05\\\/16\\\/sql-in-without-dynamic-sql\\\/\"},\"author\":{\"name\":\"Daniel Liljeberg\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#\\\/schema\\\/person\\\/e2c3fe10971c37cff2669f5688834cd7\"},\"headline\":\"SQL IN() without dynamic SQL\",\"datePublished\":\"2011-05-16T15:24:00+00:00\",\"dateModified\":\"2021-01-01T19:12:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2011\\\/05\\\/16\\\/sql-in-without-dynamic-sql\\\/\"},\"wordCount\":340,\"publisher\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#\\\/schema\\\/person\\\/e2c3fe10971c37cff2669f5688834cd7\"},\"articleSection\":[\"SQL\"],\"inLanguage\":\"sv-SE\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2011\\\/05\\\/16\\\/sql-in-without-dynamic-sql\\\/\",\"url\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2011\\\/05\\\/16\\\/sql-in-without-dynamic-sql\\\/\",\"name\":\"SQL IN() without dynamic SQL - Daniel Liljeberg\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#website\"},\"datePublished\":\"2011-05-16T15:24:00+00:00\",\"dateModified\":\"2021-01-01T19:12:13+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2011\\\/05\\\/16\\\/sql-in-without-dynamic-sql\\\/#breadcrumb\"},\"inLanguage\":\"sv-SE\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/daniel.liljeberg.io\\\/2011\\\/05\\\/16\\\/sql-in-without-dynamic-sql\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2011\\\/05\\\/16\\\/sql-in-without-dynamic-sql\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/daniel.liljeberg.io\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SQL IN() without dynamic SQL\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#website\",\"url\":\"https:\\\/\\\/daniel.liljeberg.io\\\/\",\"name\":\"Daniel Liljeberg\",\"description\":\"The is no place like 127.0.0.1\",\"publisher\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#\\\/schema\\\/person\\\/e2c3fe10971c37cff2669f5688834cd7\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/daniel.liljeberg.io\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"sv-SE\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#\\\/schema\\\/person\\\/e2c3fe10971c37cff2669f5688834cd7\",\"name\":\"Daniel Liljeberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"sv-SE\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/DanielLiljeberg.png\",\"url\":\"https:\\\/\\\/daniel.liljeberg.io\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/DanielLiljeberg.png\",\"contentUrl\":\"https:\\\/\\\/daniel.liljeberg.io\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/DanielLiljeberg.png\",\"width\":424,\"height\":440,\"caption\":\"Daniel Liljeberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/DanielLiljeberg.png\"},\"description\":\"Agile practitioner and advocate. Strong believer in the future of agile organizations, businesses and teams. Got my first computer, a C64, at age 7 and computers has been part of my life since then. Working professionally with development since the early 2000\u2019s in a vast array of technologies and roles. Social, easy going, fun loving guy with an appetite for new challenges and new knowledge who has been \u201cthere\u201d and done \u201cthat\u201d. That\u2019s a good way to sum it all up. Married and father of three kids. All true blessings ;)\",\"sameAs\":[\"https:\\\/\\\/daniel.liljeberg.io\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/danielliljeberg\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"SQL IN() without dynamic SQL - Daniel Liljeberg","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/daniel.liljeberg.io\/sv\/2011\/05\/16\/sql-in-without-dynamic-sql\/","og_locale":"sv_SE","og_type":"article","og_title":"SQL IN() without dynamic SQL - Daniel Liljeberg","og_description":"Got a question a while ago how to solve a problem that involved a SQL stored procedure containing the use of \u2018IN\u2019 whose data you submitted to the procedure. This was solved as many solve it, with dynamic SQL. This can be likened to building your SQL query from strings in your SP and then&hellip;&nbsp;Read More &raquo;SQL IN() without dynamic SQL","og_url":"https:\/\/daniel.liljeberg.io\/sv\/2011\/05\/16\/sql-in-without-dynamic-sql\/","og_site_name":"Daniel Liljeberg","article_published_time":"2011-05-16T15:24:00+00:00","article_modified_time":"2021-01-01T19:12:13+00:00","author":"Daniel Liljeberg","twitter_card":"summary_large_image","twitter_misc":{"Skriven av":"Daniel Liljeberg","Ber\u00e4knad l\u00e4stid":"2 minuter"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/daniel.liljeberg.io\/2011\/05\/16\/sql-in-without-dynamic-sql\/#article","isPartOf":{"@id":"https:\/\/daniel.liljeberg.io\/2011\/05\/16\/sql-in-without-dynamic-sql\/"},"author":{"name":"Daniel Liljeberg","@id":"https:\/\/daniel.liljeberg.io\/#\/schema\/person\/e2c3fe10971c37cff2669f5688834cd7"},"headline":"SQL IN() without dynamic SQL","datePublished":"2011-05-16T15:24:00+00:00","dateModified":"2021-01-01T19:12:13+00:00","mainEntityOfPage":{"@id":"https:\/\/daniel.liljeberg.io\/2011\/05\/16\/sql-in-without-dynamic-sql\/"},"wordCount":340,"publisher":{"@id":"https:\/\/daniel.liljeberg.io\/#\/schema\/person\/e2c3fe10971c37cff2669f5688834cd7"},"articleSection":["SQL"],"inLanguage":"sv-SE"},{"@type":"WebPage","@id":"https:\/\/daniel.liljeberg.io\/2011\/05\/16\/sql-in-without-dynamic-sql\/","url":"https:\/\/daniel.liljeberg.io\/2011\/05\/16\/sql-in-without-dynamic-sql\/","name":"SQL IN() without dynamic SQL - Daniel Liljeberg","isPartOf":{"@id":"https:\/\/daniel.liljeberg.io\/#website"},"datePublished":"2011-05-16T15:24:00+00:00","dateModified":"2021-01-01T19:12:13+00:00","breadcrumb":{"@id":"https:\/\/daniel.liljeberg.io\/2011\/05\/16\/sql-in-without-dynamic-sql\/#breadcrumb"},"inLanguage":"sv-SE","potentialAction":[{"@type":"ReadAction","target":["https:\/\/daniel.liljeberg.io\/2011\/05\/16\/sql-in-without-dynamic-sql\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/daniel.liljeberg.io\/2011\/05\/16\/sql-in-without-dynamic-sql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/daniel.liljeberg.io\/"},{"@type":"ListItem","position":2,"name":"SQL IN() without dynamic SQL"}]},{"@type":"WebSite","@id":"https:\/\/daniel.liljeberg.io\/#website","url":"https:\/\/daniel.liljeberg.io\/","name":"Daniel Liljeberg","description":"The is no place like 127.0.0.1","publisher":{"@id":"https:\/\/daniel.liljeberg.io\/#\/schema\/person\/e2c3fe10971c37cff2669f5688834cd7"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/daniel.liljeberg.io\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"sv-SE"},{"@type":["Person","Organization"],"@id":"https:\/\/daniel.liljeberg.io\/#\/schema\/person\/e2c3fe10971c37cff2669f5688834cd7","name":"Daniel Liljeberg","image":{"@type":"ImageObject","inLanguage":"sv-SE","@id":"https:\/\/daniel.liljeberg.io\/wp-content\/uploads\/2020\/12\/DanielLiljeberg.png","url":"https:\/\/daniel.liljeberg.io\/wp-content\/uploads\/2020\/12\/DanielLiljeberg.png","contentUrl":"https:\/\/daniel.liljeberg.io\/wp-content\/uploads\/2020\/12\/DanielLiljeberg.png","width":424,"height":440,"caption":"Daniel Liljeberg"},"logo":{"@id":"https:\/\/daniel.liljeberg.io\/wp-content\/uploads\/2020\/12\/DanielLiljeberg.png"},"description":"Agile practitioner and advocate. Strong believer in the future of agile organizations, businesses and teams. Got my first computer, a C64, at age 7 and computers has been part of my life since then. Working professionally with development since the early 2000\u2019s in a vast array of technologies and roles. Social, easy going, fun loving guy with an appetite for new challenges and new knowledge who has been \u201cthere\u201d and done \u201cthat\u201d. That\u2019s a good way to sum it all up. Married and father of three kids. All true blessings ;)","sameAs":["https:\/\/daniel.liljeberg.io","https:\/\/www.linkedin.com\/in\/danielliljeberg\/"]}]}},"_links":{"self":[{"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/posts\/59","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/comments?post=59"}],"version-history":[{"count":1,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/posts\/59\/revisions"}],"predecessor-version":[{"id":60,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/posts\/59\/revisions\/60"}],"wp:attachment":[{"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/media?parent=59"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/categories?post=59"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/tags?post=59"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}