0

I am having issues with how we are currently storing our SQL queries, we currently have a java class that stores the SQL as a public static final, some of these SQL queries require a global string object to be injected into the where clause such as a system name or a user name, however because we store the queries as a static final, when another test runs and the system name or user name has the value reassigned the SQL query still holds the value from the previous test, I need to find a more efficient and stable way to store the SQL queries. can anyone help?

Example of how we store our SQL queries:

public static final String GET_USER_ACCESS_VALUES =
"SELECT \n" +
                        "[Company].[dbo].[TUsers].[PINExpiryDate]\n" +
                        ",[Company].[dbo].[TUsers].[PINForceChange]\n" +
                        ",[Company].[dbo].[TUsers].[Active]\n" +
                        ",[Company].[dbo].[TUsers].[ContractExpiry]\n" +
                        ",[Company].[dbo].[TUserGroups].[Name]\n" +
                        ",[Company].[dbo].[TUsers].[ActiveDate]\n" +
                        ",[Company].[dbo].[TUsers].[ExpiryDate]\n" +
                        ",[Company].[dbo].[TUsers].[AllowanceAcrossSystemsOverride]\n" +
                        "FROM [Company].[dbo].[TUsers] \n" +
                        "INNER JOIN [Company].[dbo].[TUserGroups] \n" +
                        "ON [Company].[dbo].[TUsers].[UserGroupID] = [Company].[dbo].[TUserGroups].[UserGroupID]\n" +
                        "WHERE [Company].[dbo].[TUsers].[DisplayName] = '" + userNameValue +"'";
2
  • Sorry missed this at the start of the SQL query: public static final String GET_USER_ACCESS_VALUES = Commented Aug 5, 2022 at 9:39
  • Then edit your question to include it, please. Commented Aug 5, 2022 at 9:41

2 Answers 2

5

Don't concatenate strings like that. Use PreparedStatement with the setString method to set the user name.

PreparedStatement prep = connection.prepareStatement(GET_USER_ACCESS_VALUES);

prep.setString(1, userNameValue);

GET_USER_ACCESS_VALUES now just has a ? for the name:

public static final String GET_USER_ACCESS_VALUES = """
      SELECT
          [Company].[dbo].[TUsers].[PINExpiryDate]
          ,[Company].[dbo].[TUsers].[PINForceChange]
          ,[Company].[dbo].[TUsers].[Active]
          ,[Company].[dbo].[TUsers].[ContractExpiry]
          ,[Company].[dbo].[TUserGroups].[Name]
          ,[Company].[dbo].[TUsers].[ActiveDate]
          ,[Company].[dbo].[TUsers].[ExpiryDate]
          ,[Company].[dbo].[TUsers].[AllowanceAcrossSystemsOverride]
          FROM [Company].[dbo].[TUsers]
          INNER JOIN [Company].[dbo].[TUserGroups]
          ON [Company].[dbo].[TUsers].[UserGroupID] = [Company].[dbo].[TUserGroups].[UserGroupID]
          WHERE [Company].[dbo].[TUsers].[DisplayName] = ?
      """;

I have used a Java 15 text block here to simplify the string

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent thank you so much, I am quite new to development and I have been left with an existing framework that I am trying to improve and make more dynamic, you have been a great help thank you!
-1

You should avoid "global" variables as much as you can in your code. What @greg-449 mentioned is the best way to go. Use prepared statement.

If you have to use Strings for your SQL statements I would use something like this:

public static final String cmd = "SELECT * FROM Users WHERE NAME={0}"

And you would use it like this:

var sqlCommand = MessageData.format(cmd, currentUserName)

See https://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html

2 Comments

Thank you for the information, I am trying to improve our current framework and I am the only one on the team with about 6 months experience in development so I am having to ask questions like this, I really appreciate your help!
This is not a good way to set parameters as it does not handle punctuation (quotes around string literal) and could be used to inject malicious actions or side effects (eg some jdbc implementations would allow addition of currentUserName = "'xyz'; drop table Users"). Always use PreparedStatement and placeholder ? with bind parameters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.