T-SQL Procedure parameter name - tsql

I have to create a procedure with same parameters names as excel columns. Some loook like this 'xxx/xxx' or 'xxx - xxx'. Is there any work around to name parameteres in a stored procedure like this?

Forward slash (/) or dash (-) are not allowed in variable names
According to http://msdn.microsoft.com/en-us/library/ms175874.aspx, that means that the allowed characters are:
Letters as defined in the Unicode Standard 3.2. The Unicode
definition of letters includes Latin characters from a through z,
from A through Z, and also letter characters from other languages.
Decimal numbers from either Basic Latin or other national scripts.
The at sign (#), dollar sign ($), number sign (#), or underscore (_).

Okay first of all why would you ever want to use special characters? That is like saying I want to fry toast underwater with electricity, why can't I have an outlet to allow that? Special characters denote special things and as such many engines, not just in SQL, but most languages will not allow reserved characters for use in variables. The best you could do was put in parameters with the reversed '_' and then replace that AFTER the object was already created for echoing out. The placeholder name of '#(something)' is really arbitrary and could be #X or #LookAtMe. It's type is important to form a contract that must be fulfilled for execution but the naming is really for hooking up. Having said that if you just must have these weird names echoed out you could do something like this:
CREATE PROC pSimpleParam #My_Param INT
AS
SELECT #My_Param
GO
ALTER PROC pSimpleParam #My_Param INT
AS
SELECT
pr.name AS ParameterName
, REPLACE(pr.name, '_', '-') AS AlteredParameterName
FROM sys.procedures p
INNER JOIN sys.parameters pr ON pr.object_id = p.object_id
AND p.name = 'pSimpleParam'
GO

Related

If there's even one non-english character in any entry in a column I want have 'TRUE' in another column

There are several entries in the column, eng characters with non english characters, eng characters numbers/symbols, non eng characters with numbers/symbols etc. If there's even one non-english character in any entry in the column, I want 'TRUE' in the adjacent column.
SELECT * 
FROM companies
WHERE name LIKE '%[a-z]%';
This code doesn't work.
You can achieve this using regular expressions. Here's a regular expression that will match all ASCII printable characters along with tab (\t), new-line/line-feed (\n), and carriage return (\r).
SELECT
*,
name ~ '[^\t\n\r\x20-\x7E]' AS has_bad_chars
FROM companies
Now this will match any character that's not A-Z, a-z, 0-9, , ., ;, :, ", ', /.
Working from the assumption that the adjacent column you mention is defined in the table as
has_non_english_char boolean then try
update companies
set has_non_english_char = name ~ '[^A-Za-z0-9_.,/$]';
]
Alternatively look into character classes or include additional characters in the above. Note: The regular expression should include the 'English' characters you want to allow.
Perhaps this is not the preferred SO protocol, but I think another answer may be better than just expanding a previous one. If not community please forgive me.
Run:
with companies as
( select * from (values ('abc.com:;'), ('abc.com - "Something')) as c(name))
SELECT 'My RE',name,name ~ '[^A-Za-z0-9&_`!##$^&*()_+=\|\][{’\;:"<.,.}? -]' has_bad_chars, 'f' desirded FROM companies
union
SELECT 'Your RE',name,name ~ '[^A-Za-z0-9&_`!##$^&*()_+=\|][{’;:""<.,.}?-]', 'f' from companies
order by 2,1 desc;
Let's examine the RE themselves and see the difference:
My RE [^A-Za-z0-9&_`!##$^&*()_+=\|\][{’\;:""<.,.}? -]
Your RE [^A-Za-z0-9&_`!##$^&*()_+=\|][{’;:""<.,.}?-]
^^^
Notice the difference at the indicated position. You have '|]' while I have '|\]' also I later have a space.
See the regular expression reference from #cpburnz earlier, in particular section "9.7.3.2. Bracket Expressions".
Your RE breaks down to '[^...][...]' which breaks the RE into looking for 2 distinct set of characters telling the RE engine to find 'any character not in the first bracketed expression' followed immediately by 'any character that is in the second bracketed expression'
The difference is I escaped the right bracket ] thus removing its special meaning in the RE and making it just another character. This is the nature of REs the exact individual characters can make all the difference. If you are going to do much of this type of stuff study REs intently.
Good luck finding the exact RE you need, its out there you just need to work with it until you find it.

Are periods in object names bad practice?

For example, a constraint for a default value of 0 could be named DF__tablename.columnname.
Although my search for this being bad practice doesn't yield results, in the numerous constraints examples I've seen on SO and many other sites, I never spotted a period.
Using period in an object name is bad practice.
Don't use dot character in an identifier. Yes it can be done but the drawbacks outweigh any benefits.
tl;dr
Special characters, such as a dot, are not allowed in regular identifiers. If an identifier does not follow the rules for regular identifier, then references to the identifier must be enclosed in square brackets (or ANSI double quotes).
https://learn.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-2017
In terms of the period (dot character), using that in an identifier is not allowed in a regular identifier; but it could be used within square brackets.
The dot character is even more of a special-ish character in SQL; it's used to separate an identifier from a preceding qualifier.
SELECT mytable.mycolumn FROM mytable
We could also write that as
SELECT [mytable].[mycolumn] FROM mytable
We could also write
SELECT [mytable.mycolumn] FROM mytable
but that means something very different. With that, we aren't referencing a column named mycolumn, we are now referencing an identifier that contains a dot character.
SQL Server will deal with this just fine.
But if we do this, and start using the dot character in our identifiers, we will be causing confusion and frustration to future readers. Any benefit we would gain by using dot characters in identifiers is going to be far outweighed by the downside for others.
Similarly, why we don't create tables named WHERE (1=1) OR, or create columns named SUBSTR(foo.bar,1,10) to avoid monstrosities like
SELECT [SUBSTR(foo.bar,1,10)] FROM [WHERE (1=1)] OR]
Which may be valid SQL, but it will cause future readers to become very upset, and cause them to curse us, our descendants and loved ones. Don't make them do that. For the love of all that is good and beautiful in this world, don't use dot characters in identifiers.
It is perfectly valid to have periods in the object names. However, this requires you to use square brackets around the object name when referring to it. In case you forget these square brackets you will get some error messages that can be less intuitive to the inexperienced developer. For this reason I recommend not to use periods in the object names. I would also guess this is the main reason you don't often see examples of periods in object names on the internet.
In your example, you could use another underscore instead of the period, like this: DF__tablename_columnname

Postgresql Function to sort characters within a string

Is there a postgresql function, preferably native function, that can sort a string such as 'banana' to 'aaabnn'?
Algorithmic efficiency of sorting is not of much importance since words will never be too long. However, database join efficiency is of some but not critical importance.
There is no native function with such functionality but you can use regexp_split_to_table to do so as this:
select theword
from (select regexp_split_to_table('banana',E'(?=.)') theword) tab
order by theword;
The result will be:
theword
a
a
a
b
n
n
This (?=.) will split by each character leaving the character as separator. It will also identify spaces. If you have a word with spaces and do not want it (the space) use E'(\\s*)' matches any whitespace character. I don't recall what the E means. I will search and edit the answer asap.
As explained in the DOCs in the section "regexp_split_to_table"
EDIT: As I said: The meaning of the E before the string you can see here: What's the "E" before a Postgres string?

Using # on Variable Names

Googling I've found this DB2 Function declaration:
CREATE FUNCTION QGPL.SPLIT (
#Data VARCHAR(32000),
#Delimiter VARCHAR(5)
)
Whats means # symbol before the Variable Name?
Regards,
Pedro
The # character is simply the first character of the SQL identifier [variable name] naming the parameter defined for the arguments of the User Defined Function (UDF); slightly reformatted [because at first glance I thought that revision might make the at-symbols appear more conspicuously to be part of the name, though now I think probably not]:
CREATE FUNCTION QGPL.SPLIT
( #Data VARCHAR(32000)
, #Delimiter VARCHAR(5)
) returns ...
Put simply, the use of the # character in an identifier is highly discouraged; the use of such variant characters, although supported in standard object naming, they can cause great pains and difficulties, including some that are insurmountable:
http://www.ibm.com/support/knowledgecenter/api/content/ssw_ibm_i_71/db2/rbafzch2iden.htm
Identifiers
An identifier is a token used to form a name. An identifier in an SQL statement is an SQL identifier, a system identifier, or a host identifier.
Note: $, #, #, and all other variant characters should not be used in identifiers because the code points used to represent them vary depending on the CCSID of the string in which they are contained. If they are used, unpredictable results may occur. [...]
[Edit-addendum 17May2015]
http://www.ibm.com/support/knowledgecenter/api/content/nl/en-us/SSEPGG_10.5.0/com.ibm.db2.luw.admin.dbobj.doc/doc/c0004625.html
Naming rules in a multiple national language environment
The basic character set that can be used in database names consists of the single-byte uppercase and lowercase Latin letters (A…Z, a…z), the Arabic numerals (0…9) and the underscore character (_).
This list is augmented with three special characters (#, #, and $) to provide compatibility with host database products. Use special characters #, #, and $ with care in a multiple national language environment because they are not included in the multiple national language host (EBCDIC) invariant character set. Characters from the extended character set can also be used, depending on the code page that is being used. If you are using the database in a multiple code page environment, you must ensure that all code pages support any elements from the extended character set you plan to use.
[...]
[/Edit-addendum 17May2015]

What constitutes a Regular Indentifier

On page 34 of 70-461 Querying Microsoft SQL Server 2012 it says that an indentifier is regular if:
The rules say that the first character must be a letter in the range
A through Z (lower or uppercase), underscore (_), at sign (#), or
number sign (#). Subsequent characters can include letters, decimal
numbers, at sign, dollar sign ($), number sign, or underscore.
However on pg 271 it says:
Even though you can embed special characters such as #, #, and $ in
an identifier for a schema, table, or column name, that action makes
the identifier delimited, no longer regular.
So to clarify would having special characters like the '$' an identifier regular or not
Having $ after the first character is part of the specification that defines a regular identifier and will not require the use of a delimiter.
I found the definition in SQL Server 2008 R2 Identifiers to be clearer than the one from page 34. It is essentially the same as the one on page 271, but with more detail.
Either you have misquoted pg 271 of the book, or your version is different than mine and has an error:
If you embed special characters other than #, #, and $ in an
identifier for a schema, table, or column, name, that action makes the
identifier delimited, no longer regular.
Here is a regular expression that will match a string that complies with the definition:
^[\p{letter}_##][\p{Letter}\p{Number}_##$]*$
Regex for flavors without unicode support:
^[a-zA-Z_##][a-zA-Z\d_##$]*$