title: How to check if a proposed T-SQL object name is valid or needs to be enclosed in square brackets
body: <p>My stored procedure may be passed an arbitrary string of characters <code>@String</code> as a <code>varchar</code> or a <code>nvarchar</code>, no more than 128 characters long.</p>
  
  <p>The stored procedure needs to use that <code>@String</code> value as an object name, i.e. the name of a table, field, view or similar.</p>
  
  <p>How can I determine if the value of <code>@String</code> as supplied is a valid object name in itself - i.e. is not a reserved word and does not contain invalid characters - or if it will require enclosure within (and escape of any contained) square brackets in order to <em>make</em> it a valid object name.</p>
  
  <p>For example, "X", "Foo" and "C:\Temp\X.csv" are valid object names (yes, I've successfully used "C:\Temp\X.csv" as-is) and can be used unmodified, while "Select", "AB]C" and "1_ABC" are not valid, and would need to be changed to "[Select]", "[AB]]C]" and "[1_ABC]"</p>
  
  <p>I would prefer a solution that <em>doesn't</em> simply attempt to create an object with that name and then checks to see if it worked.</p>
  
  <p>Preference will be given to answers that are applicable over a wider range of SQL Server versions rather than only the latest version, and shorter, less complex code will be preferred over longer, more complex code.</p>
  
  <p>As an example of the problem that led me to ask this question, my SP can be passed a <code>@Name</code>, which might be "C:\Temp\X.csv" or "ABC" or "SELECT" or whatever.  My SP then creates a table, populates it and <em>then</em> (so I don't have to use dynamic SQL) changes it's name to @Name using <code>sp_rename</code>.  I need to <code>QUOTENAME(@Name)</code> where @Name = "SELECT", but not in the other two cases, yielding (in the SSMS Object Explorer) tables "dbo.C:\Temp\X.csv", "dbo.ABC" and "dbo.SELECT".  However, I also need to check if these objects exist before I run the rest of the SP, and if I <code>QUOTENAME</code> "C:\Temp\X.csv", before I pass it as the new name to <code>sp_rename</code>, it appears in the SSMS Object Explorer as "dbo.[C:\Temp\X.csv]", and I must use <code>IF OBJECT_ID('[[C:\Temp\X.csv]]]') IS NOT NULL</code> to successfully determine that it exists, <em>not</em> <code>IF OBJECT_ID('[C:\Temp\X.csv]') IS NOT NULL</code>.</p>