src/org/nutz/dao/impl/sql/SqlLiteral.java
SqlLiteral valueOf(String str) {
        reset();
        // int statementIndex = 1;
        source = str;
        if (null == source)
            return this;
        char[] cs = Strings.trim(source).toCharArray();
        StringBuilder sb;
        for (int i = 0; i < cs.length; i++) {
            char c = cs[i];
            if (c == paramChar) {
                if (cs[i + 1] == c) {
                    stack.push(c);
                    i++;
                    continue;
                }
                sb = new StringBuilder();
                i = readTokenName(cs, i, sb);
                // Fail to read token name
                if (sb.length() == 0) {
                    stack.push(c);
                } else {
                    paramIndexes.add(sb.toString(), stack.markToken());
                    // paramIndexes.add(name, stack.markToken());
                    // statementIndexes.add(name, statementIndex++);
                }
            }
            else if (c == varChar) {
                if (cs[i + 1] == varChar) {
                    stack.push(c);
                    i++;
                    continue;
                }
                sb = new StringBuilder();
                i = readTokenName(cs, i, sb);
                // Fail to read token name
                if (sb.length() == 0) {
                    stack.push(c);
                } else {
                    // varIndexes.add(sb.toString(), stack.markToken());
                    varIndexes.add(sb.toString(), stack.markToken());
                }
            }
            else {
                stack.push(c);
            }
        }
        stack.finish();

        // eval SqlType ...

        if (stack.firstEquals("SELECT") || stack.firstEquals("WITH"))
            type = SqlType.SELECT;
        else if (stack.firstEquals("UPDATE"))
            type = SqlType.UPDATE;
        else if (stack.firstEquals("INSERT"))
            type = SqlType.INSERT;
        else if (stack.firstEquals("DELETE"))
            type = SqlType.DELETE;
        else if (stack.firstEquals("CREATE"))
            type = SqlType.CREATE;
        else if (stack.firstEquals("DROP"))
            type = SqlType.DROP;
        else if (stack.firstEquals("TRUNCATE"))
            type = SqlType.TRUNCATE;
        else if (stack.firstEquals("ALTER"))
            type = SqlType.ALTER;
        else if (stack.firstEquals("EXEC"))
            type = SqlType.EXEC;
        else if (stack.firstEquals("CALL"))
            type = SqlType.CALL;
        else if (stack.firstEquals("{CALL"))
            type = SqlType.CALL;
        else
            type = SqlType.OTHER;

        return this;
    }
SqlLiteral valueOf(String str) {
        reset();
        // int statementIndex = 1;
        source = str;
        if (null == source)
            return this;
        char[] cs = Strings.trim(source).toCharArray();
        StringBuilder sb;
        for (int i = 0; i < cs.length; i++) {
            char c = cs[i];
            if (c == paramChar) {
                if (cs[i + 1] == c) {
                    stack.push(c);
                    i++;
                    continue;
                }
                sb = new StringBuilder();
                i = readTokenName(cs, i, sb);
                // Fail to read token name
                if (sb.length() == 0) {
                    stack.push(c);
                } else {
                    paramIndexes.add(sb.toString(), stack.markToken());
                    // paramIndexes.add(name, stack.markToken());
                    // statementIndexes.add(name, statementIndex++);
                }
            }
            else if (c == varChar) {
                if (cs[i + 1] == varChar) {
                    stack.push(c);
                    i++;
                    continue;
                }
                sb = new StringBuilder();
                i = readTokenName(cs, i, sb);
                // Fail to read token name
                if (sb.length() == 0) {
                    stack.push(c);
                } else {
                    // varIndexes.add(sb.toString(), stack.markToken());
                    varIndexes.add(sb.toString(), stack.markToken());
                }
            }
            else {
                stack.push(c);
            }
        }
        stack.finish();

        // eval SqlType ...

        if (stack.firstEquals("SELECT") || stack.firstEquals("WITH"))
            type = SqlType.SELECT;
        else if (stack.firstEquals("UPDATE"))
            type = SqlType.UPDATE;
        else if (stack.firstEquals("INSERT"))
            type = SqlType.INSERT;
        else if (stack.firstEquals("DELETE"))
            type = SqlType.DELETE;
        else if (stack.firstEquals("CREATE"))
            type = SqlType.CREATE;
        else if (stack.firstEquals("DROP"))
            type = SqlType.DROP;
        else if (stack.firstEquals("TRUNCATE"))
            type = SqlType.TRUNCATE;
        else if (stack.firstEquals("ALTER"))
            type = SqlType.ALTER;
        else if (stack.firstEquals("EXEC"))
            type = SqlType.EXEC;
        else if (stack.firstEquals("CALL"))
            type = SqlType.CALL;
        else if (stack.firstEquals("{CALL"))
            type = SqlType.CALL;
        else
            type = SqlType.OTHER;

        return this;
    }
[@|$][a-zA-Z0-9_-.]+

<pre>
48-57    0-9
65-90    A-Z
97-122    a-z
95        _
45        -
46        .
</pre>

@param str
@return SqlLiteral