很想找一现成的 SQL 编辑器, 可是 NO!,只好自己努力一把了!
没有拼写检查,没有自动完成,只提供根据[关键字/函数/数据类型]进行着色.
[关键字/函数/数据类型]都是 MSSQL 的,其他数据库需要参考相关资料自己动手
.dfm
object SQLEditor: TRichEdit
Font.Color = clWindowText
Font.Height = -15
Font.Name = 'Consolas'
OnChange = SQLEditorChange
end
.h
class TForm1 : public TForm
{
__published: // IDE-managed Components
TRichEdit *SQLEditor;
TMemo *Memo1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall SQLEditorChange(TObject *Sender);
private: // User declarations
TStringList * FKeywords; // 关键字
TStringList * FFunctions; // 函数
TStringList * FDatatypes; // 数据类型
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
.cpp
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
FKeywords = new TStringList;
FFunctions = new TStringList;
FDatatypes = new TStringList;
FKeywords->Add("ADD");
FKeywords->Add("ALL");
FKeywords->Add("ALTER");
FKeywords->Add("AND");
FKeywords->Add("ANY");
FKeywords->Add("AS");
FKeywords->Add("ASC");
FKeywords->Add("AUTHORIZATION");
FKeywords->Add("BACKUP");
FKeywords->Add("BEGIN");
FKeywords->Add("BETWEEN");
FKeywords->Add("BREAK");
FKeywords->Add("BROWSE");
FKeywords->Add("BULK");
FKeywords->Add("BY");
FKeywords->Add("CASCADE");
FKeywords->Add("CASE");
FKeywords->Add("CHECK");
FKeywords->Add("CHECKPOINT");
FKeywords->Add("CLOSE");
FKeywords->Add("CLUSTERED");
FKeywords->Add("COALESCE");
FKeywords->Add("COLLATE");
FKeywords->Add("COLUMN");
FKeywords->Add("COMMIT");
FKeywords->Add("COMPUTE");
FKeywords->Add("CONSTRAINT");
FKeywords->Add("CONTAINS");
FKeywords->Add("CONTAINSTABLE");
FKeywords->Add("CONTINUE");
FKeywords->Add("CONVERT");
FKeywords->Add("CREATE");
FKeywords->Add("CROSS");
FKeywords->Add("CURRENT");
FKeywords->Add("CURRENT_DATE");
FKeywords->Add("CURRENT_TIME");
FKeywords->Add("CURRENT_TIMESTAMP");
FKeywords->Add("CURRENT_USER");
FKeywords->Add("CURSOR");
FKeywords->Add("DATABASE");
FKeywords->Add("DBCC");
FKeywords->Add("DEALLOCATE");
FKeywords->Add("DECLARE");
FKeywords->Add("DEFAULT");
FKeywords->Add("DELETE");
FKeywords->Add("DENY");
FKeywords->Add("DESC");
FKeywords->Add("DISK");
FKeywords->Add("DISTINCT");
FKeywords->Add("DISTRIBUTED");
FKeywords->Add("DOUBLE");
FKeywords->Add("DROP");
FKeywords->Add("DUMP");
FKeywords->Add("ELSE");
FKeywords->Add("END");
FKeywords->Add("ERRLVL");
FKeywords->Add("ESCAPE");
FKeywords->Add("EXCEPT");
FKeywords->Add("EXEC");
FKeywords->Add("EXECUTE");
FKeywords->Add("EXISTS");
FKeywords->Add("EXIT");
FKeywords->Add("EXTERNAL");
FKeywords->Add("FETCH");
FKeywords->Add("FILE");
FKeywords->Add("FILLFACTOR");
FKeywords->Add("FOR");
FKeywords->Add("FOREIGN");
FKeywords->Add("FREETEXT");
FKeywords->Add("FREETEXTTABLE");
FKeywords->Add("FROM");
FKeywords->Add("FULL");
FKeywords->Add("FUNCTION");
FKeywords->Add("GOTO");
FKeywords->Add("GRANT");
FKeywords->Add("GROUP");
FKeywords->Add("HAVING");
FKeywords->Add("HOLDLOCK");
FKeywords->Add("IDENTITY");
FKeywords->Add("IDENTITY_INSERT");
FKeywords->Add("IDENTITYCOL");
FKeywords->Add("IF");
FKeywords->Add("IN");
FKeywords->Add("INDEX");
FKeywords->Add("INNER");
FKeywords->Add("INSERT");
FKeywords->Add("INTERSECT");
FKeywords->Add("INTO");
FKeywords->Add("IS");
FKeywords->Add("JOIN");
FKeywords->Add("KEY");
FKeywords->Add("KILL");
FKeywords->Add("LEFT");
FKeywords->Add("LIKE");
FKeywords->Add("LINENO");
FKeywords->Add("LOAD");
FKeywords->Add("MERGE");
FKeywords->Add("NATIONAL");
FKeywords->Add("NOCHECK");
FKeywords->Add("NONCLUSTERED");
FKeywords->Add("NOT");
FKeywords->Add("NULL");
FKeywords->Add("NULLIF");
FKeywords->Add("OF");
FKeywords->Add("OFF");
FKeywords->Add("OFFSETS");
FKeywords->Add("ON");
FKeywords->Add("OPEN");
FKeywords->Add("OPENDATASOURCE");
FKeywords->Add("OPENQUERY");
FKeywords->Add("OPENROWSET");
FKeywords->Add("OPENXML");
FKeywords->Add("OPTION");
FKeywords->Add("OR");
FKeywords->Add("ORDER");
FKeywords->Add("OUTER");
FKeywords->Add("OVER");
FKeywords->Add("PERCENT");
FKeywords->Add("PIVOT");
FKeywords->Add("PLAN");
FKeywords->Add("PRECISION");
FKeywords->Add("PRIMARY");
FKeywords->Add("PRINT");
FKeywords->Add("PROC");
FKeywords->Add("PROCEDURE");
FKeywords->Add("PUBLIC");
FKeywords->Add("RAISERROR");
FKeywords->Add("READ");
FKeywords->Add("READTEXT");
FKeywords->Add("RECONFIGURE");
FKeywords->Add("REFERENCES");
FKeywords->Add("REPLICATION");
FKeywords->Add("RESTORE");
FKeywords->Add("RESTRICT");
FKeywords->Add("RETURN");
FKeywords->Add("REVERT");
FKeywords->Add("REVOKE");
FKeywords->Add("RIGHT");
FKeywords->Add("ROLLBACK");
FKeywords->Add("ROWCOUNT");
FKeywords->Add("ROWGUIDCOL");
FKeywords->Add("RULE");
FKeywords->Add("SAVE");
FKeywords->Add("SCHEMA");
FKeywords->Add("SECURITYAUDIT");
FKeywords->Add("SELECT");
FKeywords->Add("SESSION_USER");
FKeywords->Add("SET");
FKeywords->Add("SETUSER");
FKeywords->Add("SHUTDOWN");
FKeywords->Add("SOME");
FKeywords->Add("STATISTICS");
FKeywords->Add("SYSTEM_USER");
FKeywords->Add("TABLE");
FKeywords->Add("TABLESAMPLE");
FKeywords->Add("TEXTSIZE");
FKeywords->Add("THEN");
FKeywords->Add("TO");
FKeywords->Add("TOP");
FKeywords->Add("TRAN");
FKeywords->Add("TRANSACTION");
FKeywords->Add("TRIGGER");
FKeywords->Add("TRUNCATE");
FKeywords->Add("TSEQUAL");
FKeywords->Add("UNION");
FKeywords->Add("UNIQUE");
FKeywords->Add("UNPIVOT");
FKeywords->Add("UPDATE");
FKeywords->Add("UPDATETEXT");
FKeywords->Add("USE");
FKeywords->Add("USER");
FKeywords->Add("VALUES");
FKeywords->Add("VARYING");
FKeywords->Add("VIEW");
FKeywords->Add("WAITFOR");
FKeywords->Add("WHEN");
FKeywords->Add("WHERE");
FKeywords->Add("WHILE");
FKeywords->Add("WITH");
FKeywords->Add("WRITETEXT");
FKeywords->Sorted = true;
FFunctions->Add("ABS");
FFunctions->Add("ACOS");
FFunctions->Add("ASCII");
FFunctions->Add("ASIN");
FFunctions->Add("ATAN");
FFunctions->Add("ATN2");
FFunctions->Add("AVG");
FFunctions->Add("CEILING");
FFunctions->Add("CHAR");
FFunctions->Add("CHARINDEX");
FFunctions->Add("CHECKSUM_AGG");
FFunctions->Add("COS");
FFunctions->Add("COT");
FFunctions->Add("COUNT");
FFunctions->Add("COUNT_BIG");
FFunctions->Add("CURRENT_TIMESTAMP");
FFunctions->Add("DATEADD");
FFunctions->Add("DATEDIFF");
FFunctions->Add("DATENAME");
FFunctions->Add("DATEPART");
FFunctions->Add("DAY");
FFunctions->Add("DEGREES");
FFunctions->Add("DIFFERENCE");
FFunctions->Add("EXP");
FFunctions->Add("FLOOR");
FFunctions->Add("GETDATE");
FFunctions->Add("GETUTCDATE");
FFunctions->Add("GROUPING");
FFunctions->Add("LEFT");
FFunctions->Add("LEN");
FFunctions->Add("LOG");
FFunctions->Add("LOG10");
FFunctions->Add("LOWER");
FFunctions->Add("LTRIM");
FFunctions->Add("MAX");
FFunctions->Add("MIN");
FFunctions->Add("MONTH");
FFunctions->Add("NCHAR");
FFunctions->Add("PATINDEX");
FFunctions->Add("PATINDEX");
FFunctions->Add("PI");
FFunctions->Add("POWER");
FFunctions->Add("QUOTENAME");
FFunctions->Add("RADIANS");
FFunctions->Add("RAND");
FFunctions->Add("REPLACE");
FFunctions->Add("REPLICATE");
FFunctions->Add("REVERSE");
FFunctions->Add("RIGHT");
FFunctions->Add("ROUND");
FFunctions->Add("RTRIM");
FFunctions->Add("SIGN");
FFunctions->Add("SIN");
FFunctions->Add("SOUNDEX");
FFunctions->Add("SPACE");
FFunctions->Add("SQRT");
FFunctions->Add("SQUARE");
FFunctions->Add("STDEV");
FFunctions->Add("STDEVP");
FFunctions->Add("STR");
FFunctions->Add("STUFF");
FFunctions->Add("SUBSTRING");
FFunctions->Add("SUM");
FFunctions->Add("SYSDATETIME");
FFunctions->Add("SYSDATETIMEOFFSET");
FFunctions->Add("SYSUTCDATETIME");
FFunctions->Add("TAN");
FFunctions->Add("TEXTPTR");
FFunctions->Add("TEXTVALID");
FFunctions->Add("UNICODE");
FFunctions->Add("UPPER");
FFunctions->Add("VAR");
FFunctions->Add("VARP");
FFunctions->Add("YEAR");
FFunctions->Sorted = true;
FDatatypes->Add("BIGINT");
FDatatypes->Add("BINARY");
FDatatypes->Add("BIT");
FDatatypes->Add("CHAR");
FDatatypes->Add("DATE");
FDatatypes->Add("DATETIME");
FDatatypes->Add("DATETIME2");
FDatatypes->Add("DATETIMEOFFSET");
FDatatypes->Add("DECIMAL");
FDatatypes->Add("FLOAT");
FDatatypes->Add("IMAGE");
FDatatypes->Add("INT");
FDatatypes->Add("MONEY");
FDatatypes->Add("NCHAR");
FDatatypes->Add("NTEXT");
FDatatypes->Add("NUMERIC");
FDatatypes->Add("NVARCHAR");
FDatatypes->Add("REAL");
FDatatypes->Add("SMALLDATETIME");
FDatatypes->Add("SMALLINT");
FDatatypes->Add("SMALLMONEY");
FDatatypes->Add("TEXT");
FDatatypes->Add("TIME");
FDatatypes->Add("TIMESTAMP");
FDatatypes->Add("TINYINT");
FDatatypes->Add("VARBINARY");
FDatatypes->Add("VARCHAR");
FDatatypes->Add("XML");
FDatatypes->Sorted = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
delete FDatatypes;
delete FFunctions;
delete FKeywords;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SQLEditorChange(TObject *Sender)
{
int LStart = SQLEditor->SelStart;
int LLength = SQLEditor->SelLength;
try
{
SQLEditor->Perform(EM_HIDESELECTION, (NativeUInt)true, 0);
int J = 0;
int Z = 0;
int L = SQLEditor->Lines->Text.Length();
wchar_t * buf = SQLEditor->Lines->Text.c_str();
SQLEditor->SelStart = 0;
SQLEditor->SelLength = L;
SQLEditor->SelAttributes->Color = SQLEditor->Font->Color;
SQLEditor->SelAttributes->Style = SQLEditor->Font->Style;
while (J < L)
{
int I, N = 0;
String S = EmptyStr;
SQLEditor->SelStart = J - Z;
if (buf[J] == 0x0A) // "\n"
{
Z++;
}
else if (buf[J] == 0x27) // "'" 字符优先
{
I = J + 1;
while (I < L)
if (buf[I] == 0x27) break;
else
{
if (buf[I] == 0x0A) N++;
I++;
}
SQLEditor->SelLength = I - J - N + 1;
SQLEditor->SelAttributes->Color = clRed;
Z += N;
J = I;
}
else if (buf[J] == '/' && buf[J+1] == '*') // 块注解
{
I = J + 2;
while (I < L)
{
if (buf[I] == 0x0A) N++;
else if (buf[I] == '*' && buf[I+1] == '/')
{
I++;
break;
}
I++;
}
SQLEditor->SelLength = I - J - N + 1;
SQLEditor->SelAttributes->Color = clGreen;
Z += N;
J = I;
}
else if ((buf[J] == '/' && buf[J+1] == '/') // 行注解
|| (buf[J] == '-' && buf[J+1] == '-'))
{
I = J + 2;
while (I < L)
{
if (buf[I] == 0x0A || buf[I] == 0x0D) break;
I++;
}
SQLEditor->SelLength = I - J + 1;
SQLEditor->SelAttributes->Color = clGreen;
J = I;
}
else
{
for (I = J; I < L; I++)
if ((buf[I] >= 'A' && buf[I] <= 'Z')
|| (buf[I] >= 'a' && buf[I] <= 'z')
|| (buf[I] >= '0' && buf[I] <= '9')
|| buf[I] == '.' || buf[I] == '_')
S += buf[I];
else break;
if (S.Length())
{
Extended E;
S = S.UpperCase();
SQLEditor->SelLength = S.Length();
if (FKeywords->Find(S, I)) //关键字
{
SQLEditor->SelAttributes->Color = clBlue;
// SQLEditor->SelAttributes->Style = TFontStyles()<<fsBold;
}
else if (FFunctions->Find(S, I)) //函数
{
SQLEditor->SelAttributes->Color = clFuchsia;
// SQLEditor->SelAttributes->Style = TFontStyles()<<fsBold;
}
else if (FDatatypes->Find(S, I)) //数据类型
{
SQLEditor->SelAttributes->Color = TColor(0x4080FF);
// SQLEditor->SelAttributes->Style = TFontStyles()<<fsBold;
}
else if (TryStrToFloat(S, E)) //数字
SQLEditor->SelAttributes->Color = clRed;
J += SQLEditor->SelLength;
J--;
}
}
J++;
}
}
__finally
{
SQLEditor->SelStart = LStart;
SQLEditor->SelLength = LLength;
SQLEditor->Perform(EM_HIDESELECTION, (NativeUInt)false, 0);
}
}
//---------------------------------------------------------------------------