According to the documentation for SQLDriverConnect,
Because of connection string and initialization file grammar, keywords and attribute values that contain the characters []{}(),;?*=!# not enclosed with braces should be avoided.
and
A DSN or connection string value enclosed with braces ({}) containing any of the characters []{}(),;?*=!# is passed intact to the driver.
Using the connection string DSN=%s;UID=%s;PWD={%s} works in SQLServer - infact if there are certain special characters then not enclosing the password in {} fails. However, using the same string for MS Access fails with "invalid password" and works when {} is removed. It also does not work with Oracle.
If the string enclosed in the {} is passed intact to the server, then shouldn't it work? Or am I missing something?
SQLDriverConnect's Access-specific page states that:
The PWD keyword should not include any of the special characters (see SQL_SPECIAL_CHARACTERS in SQLGetInfo Returned Values).
Calling the SQLGetInfo function while connected to Access and passing SQL_SPECIAL_CHARACTERS as the InfoType argument should return the forbidden characters #Andrew Gibson mentioned.
The "More Information" section of a knowledge base article has a list of special characters not recommended for use in an Access app.
IBM's DB2 has an identically named SQLGetInfo function with an identical parameter list and takes the same InfoType constant to return special characters, listed there as:
all characters except a...z, A...Z, 0...9, and underscore
Related
I'm trying to add some constraints on database creation command in PostgreSQL.
Currently, I could do
psql -c "CREATE database \" x y\"\"z' \""
Then, I will get a database named literally " x y"z' " (without the double-quotes boundary).
It seems that pgsql supports any characters in it's database name, which is cool.
But it leads me headaches when I am doing automation stuff with bash script.
Yes, some additional work could be done to handle these cases in script. But I think these kind of names are actually meaningless (at least in my situation :), so, is there a way to add some constraints on database naming. For example, only allow [a-zA-Z0-9_.]+.
Just do not use double quotes, which you should avoid anyway if at all possible. See Documentation:
SQL identifiers and key words must begin with a letter (a-z, but also
letters with diacritical marks and non-Latin letters) or an underscore
(_). Subsequent characters in an identifier or key word can be
letters, underscores, digits (0-9), or dollar signs ($). Note that
dollar signs are not allowed in identifiers according to the letter of
the SQL standard, so their use might render applications less
portable. The SQL standard will not define a key word that contains
digits or starts or ends with an underscore, so identifiers of this
form are safe against possible conflict with future extensions of the
standard. ... There is a second kind of identifier: the delimited
identifier or quoted identifier. It is formed by enclosing an
arbitrary sequence of characters in double-quotes ("). A delimited
identifier is always an identifier, never a key word. ... Quoted
identifiers can contain any character, except the character with code
zero. (To include a double quote, write two double quotes.) This
allows constructing table or column names that would otherwise not be
possible, such as ones containing spaces or ampersands.
Not doubling quoting in you examples makes those names invalid and Postgres has no problem telling about it. So just do not use them.
Alternately you could create an event trigger. Within there you can restrict object names as needed, esp useful if you have strict naming standards. This would allow for database enforcement of those standards;
create function app_validate_table_name()
returns event_trigger
language 'plpgsql'
as $$
begin
if obj.object_identity ~! '[A-Za-z$_][[A-Za-z0-9$_]{0,62}'
then
raise exception 'App Error: Request Name (%) is invalid for <Your App Name here>',obj.object_identity;
end if
return;
end ;
$$;
create event trigger app_table_event_trigger on ddl_command_end
when tag in ('ALTER TABLE', 'CREATE TABLE')
execute procedure app_validate_table_name();
While the same can be applied to other objects it unfortunately does not seem to apply to creating a database itself.
Disclamer: The above has NOT been tested.
I'm trying to write a SQL script for use in SQL plus using substitution variables defined at runtime. Is there a way to actively escape any special characters coming in?
For instance, if the variable has an ' in it, it will immediately break whatever line in the script is running it with a
ORA-01756: quoted string not properly terminated
error since I didn't complete the quote or completed it too early. I just want it to treat the variable as a string. Is there a way to tell Oracle to just treat the characters literally to set a field or similar?
In my specific case, I want to make a general case script to change a password by prompting for the user, old, and new password.
connect &&myuser/&&oldpass#mydb;
alter user &&myuser identified by &&newpass replace &&oldpass;
If the old or new password contains special characters, it could break for a plethora of reasons, including the issue I have above.
No, there is no way to escape characters in substitution variable values.
SQL*Plus substitution variables (those of type CHAR, the only other types are numeric) are always substituted verbatim. SQL*Plus pays no attention to the structure of the statements in which substitution variables appear: it just does a search-and-replace of the variables with their values, irrespective of whether doing that leaves a valid SQL statement afterwards.
Was attempting to search our directory based on an attribute whose value is a DN. However, our user RDNs are of the form CN=Surname, GivenName, which requires that the comma be quoted in the full DN. But given an attribute like manager whose value is the DN of another user, I was unable to search for all users having specific manager. I tried (manager=CN=Surname\, GivenName,CN=users,DC=mydomain,DC=com), but got a syntax error "Bad search filter". I tried various options for quoting the DN, but all either gave me a syntax error or failed to match any objects. What am I doing wrong?
(Note that if I were looking for user objects directly, I could search for simply (CN=Surname, GivenName), with no quoting required, but I was searching for users having a specific manager. The comma-containing attribute value only becomes a problem when part of a Distinguished Name.)
The problem is that quoting the comma in the Common Name is not for the benefit of the filter parser, but for the benefit of the DN parser; the attribute value passed to that by the filter has to literally contain the backslash character. Unfortunately, the backslash is also (differently) special in LDAP filters, thus the syntax errors.
The solution is simple, but it isn't as obvious as doubling the backslash; backslash in LDAP filters works like % in URIs, so you have to use a literal backslash followed by the 2-digit hexadecimal code point for a backslash:
(manager=CN=Surname\5c, Givenname,OU=org,DC=mydomain,DC=com)
It turns out there's an example of this specific use case at the very bottom of https://docs.oracle.com/cd/E19424-01/820-4811/gdxpo/index.html#6ng8i269q.
I am upgrading my JDBC connection string right now on my Azure SQL Data Warehouse to the new specifications, specifically, adding the following to it: Application Name=MyApp.
Here's my issue. I connect to my server using the following string:
jdbc:sqlserver://localhost:1234;database=mydb;encrypt=true;trustServerCertificate=true;
If I add the application name to my string, it will become the following:
jdbc:sqlserver://localhost:1234;database=mydb;encrypt=true;trustServerCertificate=true;Application Name=MyApp
See the space between Application and Name?
My question is - is this right? And do I need to encode that space to something like %20?
Nowhere in the Microsoft docs do they mention this necessity if the connection string is a URL..
EDIT 1: I found something sort of related to the JDBC connection strings, but it doesn't specify any params that may contain spaces: https://azure.microsoft.com/en-us/documentation/articles/sql-data-warehouse-connect-overview/
EDIT 2: Found this here
Escaping Values in the Connection URL
You might have to escape certain parts of the connection URL values because of the inclusion of special characters such as spaces, semicolons, and quotation marks. The JDBC driver supports escaping these characters if they are enclosed in braces. For example, {;} escapes a semicolon.
Escaped values can contain special characters (especially '=', ';', '[]', and space) but cannot contain braces. Values that must be escaped and contain braces should be added to a properties collection.
You should not have to add any escape characters for the Application Name property. The comments about escaping apply to the URL component of your connection string and not the whole connection string.
I believe, though, that you should be using ApplicationName as the property value anyways.
I'm looking over Section 3.4 of RFC 3986 trying to understand what constitutes a valid URI query parameter key, but I'm not seeing a clear answer.
The reason I'm asking is because I'm writing a Ruby class that composes a URI with query parameters. When a new parameter is added I want to validate the key. Based on experience, it seems like the key will be invalid if it requires any escaping.
I should also say that I plan to validate the key. I'm not sure how to go about validating this data either, but I do know that in all cases I should escape this value.
Advice is appreciated. Advice in the context of how validation might already be possible through say a Ruby Gem would also be a plus.
I could well be wrong, but that spec seems to say that anything following '?' or '#' is valid as long. I wonder if you should be looking more at the spec for 'application/x-www-form-urlencoded' (ie. the key/value pairs we're all used to)?
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
This is the default content type. Forms submitted with this content
type must be encoded as follows:
Control names and values are escaped. Space characters are replaced by +', and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by %HH', a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as "CR LF" pairs (i.e., `%0D%0A').
The control names/values are listed in the order they appear in the document. The name is separated from the value by =' and name/value pairs are separated from each other by &'.
I don't believe key=value is part of the RFC, it's a convention that has emerged. Wikipedia suggests this is an 'W3C recommendation'.
Seems like some good stuff to be found searching on the application/x-www-form-urlencoded content type.
http://www.w3.org/TR/REC-html40/interact/forms.html#form-data-set