我有100个具有相同模式的表,并且我有一个触发函数,只要将数据插入到该表中就更新一些列。
表架构:
public class FirebaseAuthentication {
private Activity mContext;
private FirebaseAuth mAuth;
private OnComplete mOnComplete;
public FirebaseAuthentication(Activity context) {
mContext = context;
mAuth = FirebaseAuth.getInstance();
}
public void registerUserWithEmailandPassword(String username, String password) {
mAuth.createUserWithEmailAndPassword(username, password).addOnCompleteListener(mContext, new MyCompleteListener());
}
public void loginUserWithEmailandPassword(String username, String password) {
mAuth.signInWithEmailAndPassword(username, password).addOnCompleteListener(mContext, new MyCompleteListener());
}
public FirebaseUser getCurrentUser() {
FirebaseUser user = mAuth.getCurrentUser();
return user;
}
public void signOutUser() {
mAuth.signOut();
mContext.startActivity(new Intent(mContext, LoginActivity.class));
}
public User getUserProfile() {
FirebaseUser firebaseUser = getCurrentUser();
User user = new User();
if (firebaseUser != null) {
user.setName(firebaseUser.getDisplayName());
user.setEmail(firebaseUser.getEmail());
user.setPhotoUrl(firebaseUser.getPhotoUrl());
user.setUid(firebaseUser.getUid());
user.setVerifiedEmail(firebaseUser.isEmailVerified());
}
return user;
}
public void updateUserName(String name) {
FirebaseUser firebaseUser = getCurrentUser();
if (firebaseUser != null) {
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(name)
.build();
firebaseUser.updateProfile(profileUpdates).addOnCompleteListener(new MyCompleteListener());
}
}
public void updateProfilePhoto(String uri) {
FirebaseUser firebaseUser = getCurrentUser();
if (firebaseUser != null) {
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setPhotoUri(Uri.parse(uri))
.build();
firebaseUser.updateProfile(profileUpdates).addOnCompleteListener(new MyCompleteListener());
}
}
public void updateEmailAddress(String email) {
FirebaseUser firebaseUser = getCurrentUser();
if (firebaseUser != null) {
firebaseUser.updateEmail(email).addOnCompleteListener(new MyCompleteListener());
}
}
public void sendVerificationMail() {
FirebaseUser firebaseUser = getCurrentUser();
firebaseUser.sendEmailVerification().addOnCompleteListener(new MyCompleteListener());
}
public void changePassword(String password) {
FirebaseUser user = getCurrentUser();
if (user != null) {
String newPassword = password;
user.updatePassword(newPassword).addOnCompleteListener(new MyCompleteListener());
}
}
public void sendResetLink(String email) {
FirebaseAuth auth = FirebaseAuth.getInstance();
String emailAddress = email;
auth.sendPasswordResetEmail(emailAddress).addOnCompleteListener(new MyCompleteListener());
}
public void deleteAccount() {
FirebaseUser user = getCurrentUser();
if (user != null) {
user.delete().addOnCompleteListener(new MyCompleteListener());
}
}
public interface OnComplete {
void onSuccessListner();
void onFailureListner(String message);
}
public void setOnCompleteListener(OnComplete onCompleteListener) {
mOnComplete = onCompleteListener;
}
private class MyCompleteListener implements OnCompleteListener {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
mOnComplete.onSuccessListner();
}else {
mOnComplete.onFailureListner(task.getException().getLocalizedMessage());
}
}
}
}
触发功能:
CREATE TABLE symbol_daily_ohlc (
cdate date,
open numeric(8,2),
high numeric(8,2),
low numeric(8,2),
close numeric(8,2),
sma8 numeric(8,2)
);
表上的触发器设置:
create or replace function update_sma8() RETURNS TRIGGER AS
$$
BEGIN
UPDATE symbol_daily_ohlc d SET sma8 = s.simple_mov_avg
FROM
(
SELECT sec.cdate,AVG(sec.close)
OVER(ORDER BY sec.cdate ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS
simple_mov_avg FROM symbol_daily_ohlc sec
)s where s.cdate = NEW.cdate --The newly inserted cdate
AND d.cdate = s.cdate;
RETURN NULL;
END $$ language plpgsql;
对于给定的表(即symbol_daily_ohlc),此方法效果很好。我想使用相同的触发函数,即update_sma8()与具有相同模式的任何表一起使用(我不想为不同的表重写相同的函数)。
我尝试用TG_TABLE_NAME替换表名(即symbol_daily_ohlc),但这不起作用-引发错误。那怎么办呢?
参考:SQL trigger function to UPDATE daily moving average upon INSERT
答案 0 :(得分:0)
我认为您可能必须使用SQL来生成SQL,然后运行生成的SQL。像这样:
select CONCAT('create or replace function update_sma8() RETURNS TRIGGER AS
$$
BEGIN
UPDATE ', table_name, ' d SET sma8 = s.simple_mov_avg
FROM
(
SELECT sec.cdate,AVG(sec.close)
OVER(ORDER BY sec.cdate ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS
simple_mov_avg FROM ', table_name, '
)s where s.cdate = NEW.cdate --The newly inserted cdate
AND d.cdate = s.cdate;
RETURN NULL;
END $$ language plpgsql;
') from information_schema.tables
但实际上,您应该考虑戈登的建议(以及我的跟进),并将所有数据放回到一张表中:
SELECT CONCAT('INSERT INTO all_hist SELECT ''', table_name, ''', t.* FROM ', table_name) FROM information_schema.tables
这将生成一堆将所有表数据放入all_hist的sql,该表应该具有与其他数千个表相同的架构,除了附加的列“ symbol”或其他内容。.
如果您确实需要,可以使用类似的技巧来创建一堆视图以重新创建千位表方法。
答案 1 :(得分:0)
您可以使用相同的过程来执行并返回所有表的触发器,但是不能为所有表使用相同的触发器。
这是一个动态创建带有表名后缀(使用EXECUTE format
的触发器)的块
DO $$
declare
tabs RECORD;
BEGIN
for tabs IN
(select table_name,table_schema
from information_schema.tables where table_name
like 'symbol_daily_ohlc%'
-- and table_schema like '%'
) LOOP
EXECUTE format('CREATE TRIGGER check_update_%I
AFTER INSERT ON %I.%I
FOR EACH ROW
EXECUTE PROCEDURE update_sma8()',tabs.table_name,
tabs.table_schema
,tabs.table_name);
END LOOP;
END $$;
这是您的触发器,它从TG_TABLE_NAME
create or replace function update_sma8() RETURNS TRIGGER AS
$$
BEGIN
EXECUTE format ('UPDATE %I d SET sma8 = s.simple_mov_avg
FROM
(
SELECT sec.cdate,AVG(sec.close)
OVER(ORDER BY sec.cdate ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS
simple_mov_avg FROM %I sec
)s where s.cdate = %L --The newly inserted cdate
AND d.cdate = s.cdate',TG_TABLE_NAME,TG_TABLE_NAME,NEW.cdate);
RETURN NULL;
END $$ language plpgsql;
正如其他人所建议的那样,拥有多个具有相同结构的表不是一个好主意。您应该考虑将它们合并到一个表中。