使用SQLite,可以使用C api或PHP輕鬆添加用戶定義的SQL函數。但是也可以使用Java或Groovy?使用Java或Groovy爲SQLite編寫用戶定義的SQL函數?
3
A
回答
7
事實證明,使用SQLiteJDBC編寫用戶定義的函數實際上相當簡單。這裏是一個Groovy例子:
@GrabConfig(systemClassLoader=true)
@Grab('org.xerial:sqlite-jdbc:3.6.16')
import org.sqlite.*
import java.sql.*
db = groovy.sql.Sql.newInstance("jdbc:sqlite::memory:","org.sqlite.JDBC")
// a distance function using the spherical law of cosines
Function.create(db.getConnection(), "distance", new Function() {
protected void xFunc() throws SQLException {
def lat1 = value_double(0)
def lon1 = value_double(1)
def lat2 = value_double(2)
def lon2 = value_double(3)
double theta = lon1 - lon2;
double dist = (Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))) +
(Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta)))
dist = Math.acos(dist)
dist = rad2deg(dist)
dist = dist * 60 * 1.1515
dist = dist * 1.609344
result(dist);
}
def deg2rad(deg) {
deg * Math.PI/180.0
}
def rad2deg(rad) {
rad * 180.0/Math.PI
}
})
db.execute("CREATE TABLE city(name, lat, lon)")
db.execute("INSERT INTO city(name, lat, lon) VALUES('New York City', 40.7143, -74.0060)")
db.execute("INSERT INTO city(name, lat, lon) VALUES('San Francisco', 37.7749, -122.4194)")
db.execute("INSERT INTO city(name, lat, lon) VALUES('Paris', 48.8567, 2.3510)")
db.execute("INSERT INTO city(name, lat, lon) VALUES('Cologne', 50.9407, 6.9599)")
db.eachRow("SELECT a.name as a, b.name as b, distance(a.lat, a.lon, b.lat, b.lon) as d FROM city a, city b WHERE a.name != b.name ORDER BY d;") {
println "Distance from ${it.a} to ${it.b}: ${it.d}km"
}
8
由於問題是關於在Java或Groovy的解決方案,有人可以看看這裏的Java解決方案(就像我)
下面你可以看到簡單的功能驗證,如果提供的日期是同一天:
public class IsSameDay extends Function {
@Override
protected void xFunc() throws SQLException {
if (args() != 2) {
throw new SQLException("IsSameDay(date1,date2): Invalid argument count. Requires 2, but found " + args());
}
try {
DateTime t1 = DateTime.parse(value_text(0).replace(" ", "T"));
DateTime t2 = DateTime.parse(value_text(1).replace(" ", "T"));
if (t1.getYear() == t2.getYear() && t1.getDayOfYear() == t2.getDayOfYear()) {
result(1);
} else {
result(0);
}
} catch (Exception exception) {
throw new SQLDataException("IsSameDay(date1,date2): One of Arguments is invalid: " + exception.getLocalizedMessage());
}
}
}
,如果有人需要做一個聚合函數,則可能會發現這個例子有用:
public class MyMax extends Function.Aggregate {
private long buff = 0;
public MyMax() {
}
@Override
protected void xStep() throws SQLException {
long current = value_long(0);
if (current > buff) {
buff = current;
}
}
@Override
protected void xFinal() throws SQLException {
result(buff);
}
}
累加器的工作原理是因爲在每個查詢中MyMax實例被克隆,因此在實例化對象時可以提供起始值。
末例子展示瞭如何連接功能:
Function.create(c, IsSameDay.class.getSimpleName(), new IsSameDay());
Function.create(c, MyMax.class.getSimpleName(), new MyMax());
希望有人會發現它有用。
相關問題
- 1. 編寫用戶定義函數
- 2. Lisp中的SQLITE用戶定義函數
- 3. Sqlite C用戶定義函數
- 4. 如何編譯SQLite中的用戶定義函數
- 5. 用Java調用SQL Server用戶定義函數(UDF)
- 6. SQL用戶定義的函數
- 7. 使用XQuery參數編寫SQL函數
- 8. 在SQL中爲特定數據庫使用用戶定義的函數
- 9. pyspark地圖用戶定義的函數編寫外腳本
- 10. 在Oracle用戶定義的函數中編寫select語句
- 11. 使sqlite用戶定義的函數不觸發空選擇
- 12. 在SQL中編寫自己的函數的任何可能性(用戶定義的函數SQL)
- 13. 如何在JavaScript中使用Webkit瀏覽器編寫自定義SQLite函數?
- 14. 使用While循環重寫用戶定義的函數
- 15. SQL用戶定義函數問題
- 16. SQL測試用戶定義函數
- 17. MS SQL用戶自定義函數
- 18. 使用用戶定義的函數
- 19. DB2 Java用戶定義函數
- 20. 在C編寫SQLServer用戶定義函數#
- 21. 如何在.NET中使用SQL用戶定義的函數?
- 22. 如何使用CakePHP創建用戶定義的sql函數?
- 23. 從Groovy Sql調用函數
- 24. 應用以函數爲參數的用戶自定義函數
- 25. 編寫在Hive上使用外部Java類的自定義函數
- 26. 用戶定義的iPhone上的SQLite函數
- 27. 在更新中使用SQL用戶定義函數
- 28. 如何使用c#執行sql用戶定義函數?
- 29. Java/Groovy&Grails文件編寫
- 30. Microsoft SQL:無法找到列「dbo」或用戶定義的函數或聚合